circuit-json-to-tscircuit 0.0.92 → 0.0.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-GAMHGAGS.js → chunk-B7377FUZ.js} +387 -20
- package/dist/cli/main.js +2 -6
- package/dist/lib/index.js +1 -1
- package/lib/board-converter/stages/convert-pcb-components.ts +21 -2
- package/lib/generate-board-cad-models-tsx/converter-types.ts +6 -0
- package/lib/generate-board-cad-models-tsx/execute-jscad-operation.ts +7 -0
- package/lib/generate-board-cad-models-tsx/generate-cad-model-group-model-tsx.ts +38 -11
- package/lib/generate-board-cad-models-tsx/generate-cad-model-group-tsx.ts +17 -2
- package/lib/generate-board-cad-models-tsx/generate-jscad-cad-model-prop-tsx.ts +113 -0
- package/lib/generate-board-cad-models-tsx/get-cad-model-placement-attributes.ts +3 -3
- package/lib/generate-board-cad-models-tsx/get-jscad-operation-fit-scale-factors.ts +66 -0
- package/lib/generate-board-cad-models-tsx/get-jscad-operation-in-base-model-frame.ts +179 -0
- package/lib/generate-board-cad-models-tsx/is-jscad-cad-model-group-translucent.ts +15 -0
- package/lib/generate-board-cad-models-tsx/pack-jscad-operations.ts +69 -0
- package/package.json +1 -5
- package/tests/board-grouped-jscad-cad-model-fit.test.ts +111 -0
- package/tests/board-grouped-jscad-cad-model.test.ts +28 -38
- package/tests/board-jscad-cad-model.test.ts +12 -2
- package/tests/board-mixed-url-and-jscad-cad-models.test.ts +31 -2
- package/lib/generate-board-cad-models-tsx/generate-jscad-cad-model-tsx.ts +0 -26
|
@@ -504,9 +504,9 @@ function getCadModelPlacementAttributes({
|
|
|
504
504
|
if (cadComponent.size !== void 0) {
|
|
505
505
|
attributes.push(`size={${formatPointProp(cadComponent.size)}}`);
|
|
506
506
|
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
507
|
+
attributes.push(
|
|
508
|
+
`showAsTranslucentModel={${cadComponent.show_as_translucent_model === true}}`
|
|
509
|
+
);
|
|
510
510
|
return attributes;
|
|
511
511
|
}
|
|
512
512
|
|
|
@@ -539,48 +539,397 @@ function generateCadModelTsx({
|
|
|
539
539
|
return `<cadmodel ${attributes.join(" ")} />`;
|
|
540
540
|
}
|
|
541
541
|
|
|
542
|
-
// lib/generate-board-cad-models-tsx/
|
|
543
|
-
|
|
542
|
+
// lib/generate-board-cad-models-tsx/get-jscad-operation-fit-scale-factors.ts
|
|
543
|
+
import jscad2 from "@jscad/modeling";
|
|
544
|
+
|
|
545
|
+
// lib/generate-board-cad-models-tsx/execute-jscad-operation.ts
|
|
546
|
+
import jscad from "@jscad/modeling";
|
|
547
|
+
import { executeJscadOperations } from "jscad-planner";
|
|
548
|
+
function executeJscadOperation(operation) {
|
|
549
|
+
return executeJscadOperations(jscad, operation);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// lib/generate-board-cad-models-tsx/get-jscad-operation-fit-scale-factors.ts
|
|
553
|
+
var identityScaleFactors = { x: 1, y: 1, z: 1 };
|
|
554
|
+
function getSafeScaleFactor({
|
|
555
|
+
sourceLength,
|
|
556
|
+
targetLength
|
|
557
|
+
}) {
|
|
558
|
+
return sourceLength > 0 ? targetLength / sourceLength : 1;
|
|
559
|
+
}
|
|
560
|
+
function getJscadOperationFitScaleFactors({
|
|
561
|
+
cadComponent,
|
|
562
|
+
operation
|
|
563
|
+
}) {
|
|
564
|
+
if (cadComponent.size === void 0) return identityScaleFactors;
|
|
565
|
+
const geometry = executeJscadOperation(operation);
|
|
566
|
+
if (!jscad2.geometries.geom3.isA(geometry)) return identityScaleFactors;
|
|
567
|
+
const [minimumPoint, maximumPoint] = jscad2.measurements.measureBoundingBox(geometry);
|
|
568
|
+
const modelUnitToMmScaleFactor = cadComponent.model_unit_to_mm_scale_factor ?? 1;
|
|
569
|
+
const axisScaleFactors = {
|
|
570
|
+
x: getSafeScaleFactor({
|
|
571
|
+
sourceLength: maximumPoint[0] - minimumPoint[0],
|
|
572
|
+
targetLength: cadComponent.size.x * modelUnitToMmScaleFactor
|
|
573
|
+
}),
|
|
574
|
+
y: getSafeScaleFactor({
|
|
575
|
+
sourceLength: maximumPoint[1] - minimumPoint[1],
|
|
576
|
+
targetLength: cadComponent.size.y * modelUnitToMmScaleFactor
|
|
577
|
+
}),
|
|
578
|
+
z: getSafeScaleFactor({
|
|
579
|
+
sourceLength: maximumPoint[2] - minimumPoint[2],
|
|
580
|
+
targetLength: cadComponent.size.z * modelUnitToMmScaleFactor
|
|
581
|
+
})
|
|
582
|
+
};
|
|
583
|
+
if (cadComponent.model_object_fit === "fill_bounds") {
|
|
584
|
+
return axisScaleFactors;
|
|
585
|
+
}
|
|
586
|
+
const uniformScaleFactor = Math.min(
|
|
587
|
+
axisScaleFactors.x,
|
|
588
|
+
axisScaleFactors.y,
|
|
589
|
+
axisScaleFactors.z
|
|
590
|
+
);
|
|
591
|
+
return {
|
|
592
|
+
x: uniformScaleFactor,
|
|
593
|
+
y: uniformScaleFactor,
|
|
594
|
+
z: uniformScaleFactor
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// lib/generate-board-cad-models-tsx/get-jscad-operation-in-base-model-frame.ts
|
|
599
|
+
var degreesToRadians = (angleDegrees) => angleDegrees * Math.PI / 180;
|
|
600
|
+
var getCadComponentRotation = (cadComponent) => cadComponent.rotation ?? { x: 0, y: 0, z: 0 };
|
|
601
|
+
var getModelOriginPosition = (cadComponent) => cadComponent.model_origin_position ?? { x: 0, y: 0, z: 0 };
|
|
602
|
+
var getBoardNormalRotation = (cadComponent) => {
|
|
603
|
+
switch (cadComponent.model_board_normal_direction ?? "z+") {
|
|
604
|
+
case "x+":
|
|
605
|
+
return { x: 0, y: -90, z: 0 };
|
|
606
|
+
case "x-":
|
|
607
|
+
return { x: 0, y: 90, z: 0 };
|
|
608
|
+
case "y+":
|
|
609
|
+
return { x: 90, y: 0, z: 0 };
|
|
610
|
+
case "y-":
|
|
611
|
+
return { x: -90, y: 0, z: 0 };
|
|
612
|
+
case "z-":
|
|
613
|
+
return { x: 180, y: 0, z: 0 };
|
|
614
|
+
case "z+":
|
|
615
|
+
return { x: 0, y: 0, z: 0 };
|
|
616
|
+
}
|
|
617
|
+
};
|
|
618
|
+
var rotateOperation = ({
|
|
619
|
+
operation,
|
|
620
|
+
rotationDegrees
|
|
621
|
+
}) => {
|
|
622
|
+
let rotatedOperation = operation;
|
|
623
|
+
for (const [axis, angleDegrees] of [
|
|
624
|
+
["Z", rotationDegrees.z],
|
|
625
|
+
["Y", rotationDegrees.y],
|
|
626
|
+
["X", rotationDegrees.x]
|
|
627
|
+
]) {
|
|
628
|
+
if (angleDegrees === 0) continue;
|
|
629
|
+
rotatedOperation = {
|
|
630
|
+
type: `rotate${axis}`,
|
|
631
|
+
angle: degreesToRadians(angleDegrees),
|
|
632
|
+
shape: rotatedOperation
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
return rotatedOperation;
|
|
636
|
+
};
|
|
637
|
+
var rotateOperationByInverse = ({
|
|
638
|
+
operation,
|
|
639
|
+
rotationDegrees
|
|
640
|
+
}) => {
|
|
641
|
+
let rotatedOperation = operation;
|
|
642
|
+
for (const [axis, angleDegrees] of [
|
|
643
|
+
["X", rotationDegrees.x],
|
|
644
|
+
["Y", rotationDegrees.y],
|
|
645
|
+
["Z", rotationDegrees.z]
|
|
646
|
+
]) {
|
|
647
|
+
if (angleDegrees === 0) continue;
|
|
648
|
+
rotatedOperation = {
|
|
649
|
+
type: `rotate${axis}`,
|
|
650
|
+
angle: degreesToRadians(-angleDegrees),
|
|
651
|
+
shape: rotatedOperation
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
return rotatedOperation;
|
|
655
|
+
};
|
|
656
|
+
var translateOperation = ({
|
|
657
|
+
operation,
|
|
658
|
+
translation
|
|
659
|
+
}) => {
|
|
660
|
+
if (translation.x === 0 && translation.y === 0 && translation.z === 0) {
|
|
661
|
+
return operation;
|
|
662
|
+
}
|
|
663
|
+
return {
|
|
664
|
+
type: "translate",
|
|
665
|
+
vector: [translation.x, translation.y, translation.z],
|
|
666
|
+
shape: operation
|
|
667
|
+
};
|
|
668
|
+
};
|
|
669
|
+
var scaleOperation = ({
|
|
670
|
+
operation,
|
|
671
|
+
scaleFactors
|
|
672
|
+
}) => {
|
|
673
|
+
if (scaleFactors.x === 1 && scaleFactors.y === 1 && scaleFactors.z === 1) {
|
|
674
|
+
return operation;
|
|
675
|
+
}
|
|
676
|
+
return {
|
|
677
|
+
type: "scale",
|
|
678
|
+
factors: [scaleFactors.x, scaleFactors.y, scaleFactors.z],
|
|
679
|
+
shape: operation
|
|
680
|
+
};
|
|
681
|
+
};
|
|
682
|
+
function getJscadOperationInBaseModelFrame({
|
|
683
|
+
baseCadComponent,
|
|
684
|
+
basePositionOffset,
|
|
685
|
+
cadComponent,
|
|
686
|
+
positionOffset
|
|
687
|
+
}) {
|
|
688
|
+
if (cadComponent.model_jscad === void 0) return void 0;
|
|
689
|
+
const modelOriginPosition = getModelOriginPosition(cadComponent);
|
|
690
|
+
const cadRotationDegrees = getCadComponentRotation(cadComponent);
|
|
691
|
+
const baseCadRotationDegrees = getCadComponentRotation(baseCadComponent);
|
|
692
|
+
const modelUnitToMmScaleFactor = cadComponent.model_unit_to_mm_scale_factor ?? 1;
|
|
693
|
+
let operation = cadComponent.model_jscad;
|
|
694
|
+
operation = scaleOperation({
|
|
695
|
+
operation,
|
|
696
|
+
scaleFactors: {
|
|
697
|
+
x: modelUnitToMmScaleFactor,
|
|
698
|
+
y: modelUnitToMmScaleFactor,
|
|
699
|
+
z: modelUnitToMmScaleFactor
|
|
700
|
+
}
|
|
701
|
+
});
|
|
702
|
+
operation = translateOperation({
|
|
703
|
+
operation,
|
|
704
|
+
translation: {
|
|
705
|
+
x: -modelOriginPosition.x,
|
|
706
|
+
y: -modelOriginPosition.y,
|
|
707
|
+
z: -modelOriginPosition.z
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
operation = rotateOperation({
|
|
711
|
+
operation,
|
|
712
|
+
rotationDegrees: getBoardNormalRotation(cadComponent)
|
|
713
|
+
});
|
|
714
|
+
operation = scaleOperation({
|
|
715
|
+
operation,
|
|
716
|
+
scaleFactors: getJscadOperationFitScaleFactors({
|
|
717
|
+
cadComponent,
|
|
718
|
+
operation
|
|
719
|
+
})
|
|
720
|
+
});
|
|
721
|
+
operation = rotateOperation({
|
|
722
|
+
operation,
|
|
723
|
+
rotationDegrees: cadRotationDegrees
|
|
724
|
+
});
|
|
725
|
+
operation = translateOperation({
|
|
726
|
+
operation,
|
|
727
|
+
translation: {
|
|
728
|
+
x: positionOffset.x - basePositionOffset.x,
|
|
729
|
+
y: positionOffset.y - basePositionOffset.y,
|
|
730
|
+
z: positionOffset.z - basePositionOffset.z
|
|
731
|
+
}
|
|
732
|
+
});
|
|
733
|
+
return rotateOperationByInverse({
|
|
734
|
+
operation,
|
|
735
|
+
rotationDegrees: baseCadRotationDegrees
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// lib/generate-board-cad-models-tsx/pack-jscad-operations.ts
|
|
740
|
+
import jscad3 from "@jscad/modeling";
|
|
741
|
+
import "jscad-planner";
|
|
742
|
+
var copyPolygon = ({
|
|
743
|
+
polygon,
|
|
744
|
+
geometryColor
|
|
745
|
+
}) => ({
|
|
746
|
+
vertices: polygon.vertices.map(([x, y, z]) => [x, y, z]),
|
|
747
|
+
color: polygon.color ?? geometryColor
|
|
748
|
+
});
|
|
749
|
+
var getPackedJscadSize = (polygons) => {
|
|
750
|
+
const vertices = polygons.flatMap((polygon) => polygon.vertices);
|
|
751
|
+
if (vertices.length === 0) return void 0;
|
|
752
|
+
const [firstVertex, ...remainingVertices] = vertices;
|
|
753
|
+
let minX = firstVertex[0];
|
|
754
|
+
let minY = firstVertex[1];
|
|
755
|
+
let minZ = firstVertex[2];
|
|
756
|
+
let maxX = firstVertex[0];
|
|
757
|
+
let maxY = firstVertex[1];
|
|
758
|
+
let maxZ = firstVertex[2];
|
|
759
|
+
for (const [x, y, z] of remainingVertices) {
|
|
760
|
+
minX = Math.min(minX, x);
|
|
761
|
+
minY = Math.min(minY, y);
|
|
762
|
+
minZ = Math.min(minZ, z);
|
|
763
|
+
maxX = Math.max(maxX, x);
|
|
764
|
+
maxY = Math.max(maxY, y);
|
|
765
|
+
maxZ = Math.max(maxZ, z);
|
|
766
|
+
}
|
|
767
|
+
return { x: maxX - minX, y: maxY - minY, z: maxZ - minZ };
|
|
768
|
+
};
|
|
769
|
+
var packJscadOperations = (operations) => {
|
|
770
|
+
const polygons = [];
|
|
771
|
+
for (const operation of operations) {
|
|
772
|
+
const geometry = executeJscadOperation(operation);
|
|
773
|
+
if (!jscad3.geometries.geom3.isA(geometry)) return void 0;
|
|
774
|
+
polygons.push(
|
|
775
|
+
...jscad3.geometries.geom3.toPolygons(geometry).map(
|
|
776
|
+
(polygon) => copyPolygon({
|
|
777
|
+
polygon,
|
|
778
|
+
geometryColor: geometry.color
|
|
779
|
+
})
|
|
780
|
+
)
|
|
781
|
+
);
|
|
782
|
+
}
|
|
783
|
+
return {
|
|
784
|
+
jscad: { type: "createGeom3", polygons },
|
|
785
|
+
size: getPackedJscadSize(polygons)
|
|
786
|
+
};
|
|
787
|
+
};
|
|
788
|
+
|
|
789
|
+
// lib/generate-board-cad-models-tsx/generate-jscad-cad-model-prop-tsx.ts
|
|
790
|
+
function generateSingleJscadCadModelPropTsx({
|
|
544
791
|
cadComponent,
|
|
545
792
|
parentPlacement,
|
|
546
793
|
pcbBoard
|
|
547
794
|
}) {
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
795
|
+
const placement = getCadModelPlacement({
|
|
796
|
+
cadComponent,
|
|
797
|
+
parentPlacement,
|
|
798
|
+
pcbBoard
|
|
799
|
+
});
|
|
800
|
+
const properties = [
|
|
801
|
+
`jscad: ${JSON.stringify(cadComponent.model_jscad)}`,
|
|
802
|
+
`positionOffset: ${formatPointProp(placement.positionOffset)}`,
|
|
803
|
+
`rotationOffset: ${formatPointProp(placement.ccwRotationOffsetDegrees)}`
|
|
804
|
+
];
|
|
805
|
+
const modelOriginPosition = getCadModelOriginPosition(cadComponent);
|
|
806
|
+
if (modelOriginPosition !== void 0) {
|
|
807
|
+
properties.push(
|
|
808
|
+
`modelOriginPosition: ${formatPointProp(modelOriginPosition)}`
|
|
809
|
+
);
|
|
810
|
+
}
|
|
811
|
+
if (cadComponent.model_unit_to_mm_scale_factor !== void 0) {
|
|
812
|
+
properties.push(
|
|
813
|
+
`modelUnitToMmScale: ${cadComponent.model_unit_to_mm_scale_factor}`
|
|
814
|
+
);
|
|
815
|
+
}
|
|
816
|
+
if (cadComponent.model_board_normal_direction !== void 0) {
|
|
817
|
+
properties.push(
|
|
818
|
+
`modelBoardNormalDirection: ${JSON.stringify(cadComponent.model_board_normal_direction)}`
|
|
819
|
+
);
|
|
820
|
+
}
|
|
821
|
+
if (cadComponent.size !== void 0) {
|
|
822
|
+
properties.push(`size: ${formatPointProp(cadComponent.size)}`);
|
|
823
|
+
}
|
|
824
|
+
return `{ ${properties.join(", ")} }`;
|
|
825
|
+
}
|
|
826
|
+
function generateJscadCadModelPropTsx({
|
|
827
|
+
cadComponents,
|
|
828
|
+
parentPlacement,
|
|
829
|
+
pcbBoard
|
|
830
|
+
}) {
|
|
831
|
+
const baseCadComponent = cadComponents[0];
|
|
832
|
+
if (!baseCadComponent || baseCadComponent.model_jscad === void 0) {
|
|
833
|
+
return void 0;
|
|
834
|
+
}
|
|
835
|
+
if (cadComponents.length === 1) {
|
|
836
|
+
return generateSingleJscadCadModelPropTsx({
|
|
837
|
+
cadComponent: baseCadComponent,
|
|
838
|
+
parentPlacement,
|
|
839
|
+
pcbBoard
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
const basePlacement = getCadModelPlacement({
|
|
843
|
+
cadComponent: baseCadComponent,
|
|
844
|
+
parentPlacement,
|
|
845
|
+
pcbBoard
|
|
846
|
+
});
|
|
847
|
+
const shapes = cadComponents.flatMap((cadComponent) => {
|
|
848
|
+
const placement = getCadModelPlacement({
|
|
552
849
|
cadComponent,
|
|
553
850
|
parentPlacement,
|
|
554
851
|
pcbBoard
|
|
555
|
-
})
|
|
852
|
+
});
|
|
853
|
+
const operation = getJscadOperationInBaseModelFrame({
|
|
854
|
+
baseCadComponent,
|
|
855
|
+
basePositionOffset: basePlacement.positionOffset,
|
|
856
|
+
cadComponent,
|
|
857
|
+
positionOffset: placement.positionOffset
|
|
858
|
+
});
|
|
859
|
+
return operation ? [operation] : [];
|
|
860
|
+
});
|
|
861
|
+
if (shapes.length === 0) return void 0;
|
|
862
|
+
const packedJscadOperations = packJscadOperations(shapes);
|
|
863
|
+
const jscad4 = packedJscadOperations?.jscad ?? {
|
|
864
|
+
type: "union",
|
|
865
|
+
shapes
|
|
866
|
+
};
|
|
867
|
+
const properties = [
|
|
868
|
+
`jscad: ${JSON.stringify(jscad4)}`,
|
|
869
|
+
`positionOffset: ${formatPointProp(basePlacement.positionOffset)}`,
|
|
870
|
+
`rotationOffset: ${formatPointProp(basePlacement.ccwRotationOffsetDegrees)}`,
|
|
871
|
+
`modelOriginPosition: ${formatPointProp({ x: 0, y: 0, z: 0 })}`,
|
|
872
|
+
"modelUnitToMmScale: 1",
|
|
873
|
+
'modelBoardNormalDirection: "z+"'
|
|
556
874
|
];
|
|
557
|
-
|
|
875
|
+
if (packedJscadOperations?.size !== void 0) {
|
|
876
|
+
properties.push(`size: ${formatPointProp(packedJscadOperations.size)}`);
|
|
877
|
+
}
|
|
878
|
+
return `{ ${properties.join(", ")} }`;
|
|
558
879
|
}
|
|
559
880
|
|
|
560
881
|
// lib/generate-board-cad-models-tsx/generate-cad-model-group-model-tsx.ts
|
|
561
|
-
var
|
|
882
|
+
var generateUrlCadModelElementsTsx = ({
|
|
562
883
|
cadModelGroup,
|
|
563
884
|
pcbBoard
|
|
564
885
|
}) => cadModelGroup.cadComponents.flatMap((cadComponent) => {
|
|
565
|
-
|
|
566
|
-
const modelElement =
|
|
886
|
+
if (getCadModelUrl(cadComponent) === void 0) return [];
|
|
887
|
+
const modelElement = generateCadModelTsx({
|
|
567
888
|
cadComponent,
|
|
568
889
|
parentPlacement: cadModelGroup.parentPlacement,
|
|
569
890
|
pcbBoard
|
|
570
891
|
});
|
|
571
892
|
return modelElement ? [modelElement] : [];
|
|
572
893
|
});
|
|
894
|
+
var getJscadCadComponents = (cadModelGroup) => cadModelGroup.cadComponents.filter(
|
|
895
|
+
(cadComponent) => cadComponent.model_jscad !== void 0
|
|
896
|
+
);
|
|
573
897
|
function generateCadModelGroupModelTsx({
|
|
574
898
|
cadModelGroup,
|
|
575
899
|
pcbBoard
|
|
576
900
|
}) {
|
|
577
|
-
const
|
|
901
|
+
const jscadCadComponents = getJscadCadComponents(cadModelGroup);
|
|
902
|
+
if (jscadCadComponents.length > 0) {
|
|
903
|
+
return generateJscadCadModelPropTsx({
|
|
904
|
+
cadComponents: jscadCadComponents,
|
|
905
|
+
parentPlacement: cadModelGroup.parentPlacement,
|
|
906
|
+
pcbBoard
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
const urlCadModelElementsTsx = generateUrlCadModelElementsTsx({
|
|
578
910
|
cadModelGroup,
|
|
579
911
|
pcbBoard
|
|
580
912
|
});
|
|
581
|
-
if (
|
|
582
|
-
if (
|
|
583
|
-
return `<cadassembly>${
|
|
913
|
+
if (urlCadModelElementsTsx.length === 0) return void 0;
|
|
914
|
+
if (urlCadModelElementsTsx.length === 1) return urlCadModelElementsTsx[0];
|
|
915
|
+
return `<cadassembly>${urlCadModelElementsTsx.join("\n")}</cadassembly>`;
|
|
916
|
+
}
|
|
917
|
+
function generateCadModelGroupChildrenTsx({
|
|
918
|
+
cadModelGroup,
|
|
919
|
+
pcbBoard
|
|
920
|
+
}) {
|
|
921
|
+
if (getJscadCadComponents(cadModelGroup).length === 0) return [];
|
|
922
|
+
return generateUrlCadModelElementsTsx({ cadModelGroup, pcbBoard });
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
// lib/generate-board-cad-models-tsx/is-jscad-cad-model-group-translucent.ts
|
|
926
|
+
function isJscadCadModelGroupTranslucent(cadModelGroup) {
|
|
927
|
+
const jscadCadComponents = cadModelGroup.cadComponents.filter(
|
|
928
|
+
(cadComponent) => cadComponent.model_jscad !== void 0
|
|
929
|
+
);
|
|
930
|
+
return jscadCadComponents.length > 0 && jscadCadComponents.every(
|
|
931
|
+
(cadComponent) => cadComponent.show_as_translucent_model === true
|
|
932
|
+
);
|
|
584
933
|
}
|
|
585
934
|
|
|
586
935
|
// lib/generate-board-cad-models-tsx/generate-cad-model-group-tsx.ts
|
|
@@ -606,7 +955,17 @@ function generateCadModelGroupTsx({
|
|
|
606
955
|
"footprint={<footprint />}",
|
|
607
956
|
`cadModel={${cadModelTsx}}`
|
|
608
957
|
];
|
|
609
|
-
|
|
958
|
+
if (isJscadCadModelGroupTranslucent(cadModelGroup)) {
|
|
959
|
+
attributes.push("showAsTranslucentModel");
|
|
960
|
+
}
|
|
961
|
+
const childModelElementsTsx = generateCadModelGroupChildrenTsx({
|
|
962
|
+
cadModelGroup,
|
|
963
|
+
pcbBoard
|
|
964
|
+
});
|
|
965
|
+
if (childModelElementsTsx.length === 0) {
|
|
966
|
+
return `<chip ${attributes.join(" ")} />`;
|
|
967
|
+
}
|
|
968
|
+
return `<chip ${attributes.join(" ")}>${childModelElementsTsx.join("\n")}</chip>`;
|
|
610
969
|
}
|
|
611
970
|
|
|
612
971
|
// lib/board-converter/stages/convert-board-cad-models.ts
|
|
@@ -3513,6 +3872,10 @@ var convertPcbComponents = ({
|
|
|
3513
3872
|
cadModelGroup: localizedCadModelGroup,
|
|
3514
3873
|
pcbBoard
|
|
3515
3874
|
}) : void 0;
|
|
3875
|
+
const childModelElementsTsx = localizedCadModelGroup ? generateCadModelGroupChildrenTsx({
|
|
3876
|
+
cadModelGroup: localizedCadModelGroup,
|
|
3877
|
+
pcbBoard
|
|
3878
|
+
}) : [];
|
|
3516
3879
|
const componentProps = [
|
|
3517
3880
|
`name=${formatJsxStringAttribute(componentName)}`,
|
|
3518
3881
|
`pcbX={${componentPosition.x}}`,
|
|
@@ -3524,6 +3887,9 @@ var convertPcbComponents = ({
|
|
|
3524
3887
|
if (cadModelTsx) {
|
|
3525
3888
|
componentProps.push(`cadModel={${cadModelTsx}}`);
|
|
3526
3889
|
}
|
|
3890
|
+
if (localizedCadModelGroup && isJscadCadModelGroupTranslucent(localizedCadModelGroup)) {
|
|
3891
|
+
componentProps.push("showAsTranslucentModel");
|
|
3892
|
+
}
|
|
3527
3893
|
if (pinLabels) {
|
|
3528
3894
|
componentProps.push(`pinLabels={${JSON.stringify(pinLabels)}}`);
|
|
3529
3895
|
}
|
|
@@ -3543,8 +3909,9 @@ var convertPcbComponents = ({
|
|
|
3543
3909
|
if (pcbComponent.obstructs_within_bounds === false) {
|
|
3544
3910
|
componentProps.push("obstructsWithinBounds={false}");
|
|
3545
3911
|
}
|
|
3912
|
+
const chipOpeningTsx = `<chip ${componentProps.join(" ")} footprint={${footprintTsx ?? "<footprint />"}}`;
|
|
3546
3913
|
boardChildren.push(
|
|
3547
|
-
|
|
3914
|
+
childModelElementsTsx.length === 0 ? `${chipOpeningTsx} />` : `${chipOpeningTsx}>${childModelElementsTsx.join("\n")}</chip>`
|
|
3548
3915
|
);
|
|
3549
3916
|
}
|
|
3550
3917
|
};
|
package/dist/cli/main.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
convertCircuitJsonToTscircuit
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-B7377FUZ.js";
|
|
5
5
|
|
|
6
6
|
// cli/main.ts
|
|
7
7
|
import { Command } from "commander";
|
|
@@ -16,7 +16,7 @@ var package_default = {
|
|
|
16
16
|
"./cli": "./dist/cli/main.js"
|
|
17
17
|
},
|
|
18
18
|
type: "module",
|
|
19
|
-
version: "0.0.
|
|
19
|
+
version: "0.0.92",
|
|
20
20
|
repository: {
|
|
21
21
|
type: "git",
|
|
22
22
|
url: "https://github.com/tscircuit/circuit-json-to-tscircuit.git"
|
|
@@ -58,10 +58,6 @@ var package_default = {
|
|
|
58
58
|
},
|
|
59
59
|
peerDependencies: {
|
|
60
60
|
typescript: "^5.0.0"
|
|
61
|
-
},
|
|
62
|
-
overrides: {
|
|
63
|
-
"@tscircuit/core": "https://pkg.pr.new/tscircuit/core/@tscircuit/core@3013d38",
|
|
64
|
-
"@tscircuit/props": "https://pkg.pr.new/@tscircuit/props@074b67d"
|
|
65
61
|
}
|
|
66
62
|
};
|
|
67
63
|
|
package/dist/lib/index.js
CHANGED
|
@@ -2,8 +2,12 @@ import type { AnyCircuitElement, PcbComponent } from "circuit-json"
|
|
|
2
2
|
import type { BoardConversionContext as FootprintConversionContext } from "../../board-conversion-context"
|
|
3
3
|
import { formatJsxStringAttribute } from "../../format-jsx-string-attribute"
|
|
4
4
|
import type { CadModelGroup } from "../../generate-board-cad-models-tsx/converter-types"
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
generateCadModelGroupChildrenTsx,
|
|
7
|
+
generateCadModelGroupModelTsx,
|
|
8
|
+
} from "../../generate-board-cad-models-tsx/generate-cad-model-group-model-tsx"
|
|
6
9
|
import { getCadModelGroups } from "../../generate-board-cad-models-tsx/get-cad-model-groups"
|
|
10
|
+
import { isJscadCadModelGroupTranslucent } from "../../generate-board-cad-models-tsx/is-jscad-cad-model-group-translucent"
|
|
7
11
|
import { generateFootprintTsx } from "../../generate-footprint-tsx"
|
|
8
12
|
import type { BoardConverterStage } from "../BoardConverterContext"
|
|
9
13
|
import { getPcbComponentRenderPlacement } from "../get-pcb-component-render-placement"
|
|
@@ -130,6 +134,12 @@ export const convertPcbComponents: BoardConverterStage = ({
|
|
|
130
134
|
pcbBoard,
|
|
131
135
|
})
|
|
132
136
|
: undefined
|
|
137
|
+
const childModelElementsTsx = localizedCadModelGroup
|
|
138
|
+
? generateCadModelGroupChildrenTsx({
|
|
139
|
+
cadModelGroup: localizedCadModelGroup,
|
|
140
|
+
pcbBoard,
|
|
141
|
+
})
|
|
142
|
+
: []
|
|
133
143
|
const componentProps = [
|
|
134
144
|
`name=${formatJsxStringAttribute(componentName)}`,
|
|
135
145
|
`pcbX={${componentPosition.x}}`,
|
|
@@ -142,6 +152,12 @@ export const convertPcbComponents: BoardConverterStage = ({
|
|
|
142
152
|
if (cadModelTsx) {
|
|
143
153
|
componentProps.push(`cadModel={${cadModelTsx}}`)
|
|
144
154
|
}
|
|
155
|
+
if (
|
|
156
|
+
localizedCadModelGroup &&
|
|
157
|
+
isJscadCadModelGroupTranslucent(localizedCadModelGroup)
|
|
158
|
+
) {
|
|
159
|
+
componentProps.push("showAsTranslucentModel")
|
|
160
|
+
}
|
|
145
161
|
if (pinLabels) {
|
|
146
162
|
componentProps.push(`pinLabels={${JSON.stringify(pinLabels)}}`)
|
|
147
163
|
}
|
|
@@ -164,8 +180,11 @@ export const convertPcbComponents: BoardConverterStage = ({
|
|
|
164
180
|
if (pcbComponent.obstructs_within_bounds === false) {
|
|
165
181
|
componentProps.push("obstructsWithinBounds={false}")
|
|
166
182
|
}
|
|
183
|
+
const chipOpeningTsx = `<chip ${componentProps.join(" ")} footprint={${footprintTsx ?? "<footprint />"}}`
|
|
167
184
|
boardChildren.push(
|
|
168
|
-
|
|
185
|
+
childModelElementsTsx.length === 0
|
|
186
|
+
? `${chipOpeningTsx} />`
|
|
187
|
+
: `${chipOpeningTsx}>${childModelElementsTsx.join("\n")}</chip>`,
|
|
169
188
|
)
|
|
170
189
|
}
|
|
171
190
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import jscad from "@jscad/modeling"
|
|
2
|
+
import { executeJscadOperations, type JscadOperation } from "jscad-planner"
|
|
3
|
+
|
|
4
|
+
export function executeJscadOperation(operation: JscadOperation): unknown {
|
|
5
|
+
// @ts-expect-error @jscad/modeling overloads differ from the planner adapter.
|
|
6
|
+
return executeJscadOperations(jscad, operation)
|
|
7
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { PcbBoard } from "circuit-json"
|
|
2
2
|
import type { CadModelGroup } from "./converter-types"
|
|
3
3
|
import { generateCadModelTsx } from "./generate-cad-model-tsx"
|
|
4
|
-
import {
|
|
4
|
+
import { generateJscadCadModelPropTsx } from "./generate-jscad-cad-model-prop-tsx"
|
|
5
|
+
import { getCadModelUrl } from "./get-cad-model-url"
|
|
5
6
|
|
|
6
|
-
const
|
|
7
|
+
const generateUrlCadModelElementsTsx = ({
|
|
7
8
|
cadModelGroup,
|
|
8
9
|
pcbBoard,
|
|
9
10
|
}: {
|
|
@@ -11,11 +12,9 @@ const generateCadModelElementsTsx = ({
|
|
|
11
12
|
pcbBoard: PcbBoard
|
|
12
13
|
}): string[] =>
|
|
13
14
|
cadModelGroup.cadComponents.flatMap((cadComponent) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
: generateJscadCadModelTsx
|
|
18
|
-
const modelElement = modelElementGenerator({
|
|
15
|
+
if (getCadModelUrl(cadComponent) === undefined) return []
|
|
16
|
+
|
|
17
|
+
const modelElement = generateCadModelTsx({
|
|
19
18
|
cadComponent,
|
|
20
19
|
parentPlacement: cadModelGroup.parentPlacement,
|
|
21
20
|
pcbBoard,
|
|
@@ -23,6 +22,13 @@ const generateCadModelElementsTsx = ({
|
|
|
23
22
|
return modelElement ? [modelElement] : []
|
|
24
23
|
})
|
|
25
24
|
|
|
25
|
+
const getJscadCadComponents = (
|
|
26
|
+
cadModelGroup: CadModelGroup,
|
|
27
|
+
): CadModelGroup["cadComponents"] =>
|
|
28
|
+
cadModelGroup.cadComponents.filter(
|
|
29
|
+
(cadComponent) => cadComponent.model_jscad !== undefined,
|
|
30
|
+
)
|
|
31
|
+
|
|
26
32
|
export function generateCadModelGroupModelTsx({
|
|
27
33
|
cadModelGroup,
|
|
28
34
|
pcbBoard,
|
|
@@ -30,12 +36,33 @@ export function generateCadModelGroupModelTsx({
|
|
|
30
36
|
cadModelGroup: CadModelGroup
|
|
31
37
|
pcbBoard: PcbBoard
|
|
32
38
|
}): string | undefined {
|
|
33
|
-
const
|
|
39
|
+
const jscadCadComponents = getJscadCadComponents(cadModelGroup)
|
|
40
|
+
if (jscadCadComponents.length > 0) {
|
|
41
|
+
return generateJscadCadModelPropTsx({
|
|
42
|
+
cadComponents: jscadCadComponents,
|
|
43
|
+
parentPlacement: cadModelGroup.parentPlacement,
|
|
44
|
+
pcbBoard,
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const urlCadModelElementsTsx = generateUrlCadModelElementsTsx({
|
|
34
49
|
cadModelGroup,
|
|
35
50
|
pcbBoard,
|
|
36
51
|
})
|
|
37
|
-
if (
|
|
38
|
-
if (
|
|
52
|
+
if (urlCadModelElementsTsx.length === 0) return undefined
|
|
53
|
+
if (urlCadModelElementsTsx.length === 1) return urlCadModelElementsTsx[0]
|
|
54
|
+
|
|
55
|
+
return `<cadassembly>${urlCadModelElementsTsx.join("\n")}</cadassembly>`
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function generateCadModelGroupChildrenTsx({
|
|
59
|
+
cadModelGroup,
|
|
60
|
+
pcbBoard,
|
|
61
|
+
}: {
|
|
62
|
+
cadModelGroup: CadModelGroup
|
|
63
|
+
pcbBoard: PcbBoard
|
|
64
|
+
}): string[] {
|
|
65
|
+
if (getJscadCadComponents(cadModelGroup).length === 0) return []
|
|
39
66
|
|
|
40
|
-
return
|
|
67
|
+
return generateUrlCadModelElementsTsx({ cadModelGroup, pcbBoard })
|
|
41
68
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { PcbBoard } from "circuit-json"
|
|
2
2
|
import type { CadModelGroup } from "./converter-types"
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
generateCadModelGroupChildrenTsx,
|
|
5
|
+
generateCadModelGroupModelTsx,
|
|
6
|
+
} from "./generate-cad-model-group-model-tsx"
|
|
7
|
+
import { isJscadCadModelGroupTranslucent } from "./is-jscad-cad-model-group-translucent"
|
|
4
8
|
|
|
5
9
|
export function generateCadModelGroupTsx({
|
|
6
10
|
cadModelGroup,
|
|
@@ -29,5 +33,16 @@ export function generateCadModelGroupTsx({
|
|
|
29
33
|
"footprint={<footprint />}",
|
|
30
34
|
`cadModel={${cadModelTsx}}`,
|
|
31
35
|
]
|
|
32
|
-
|
|
36
|
+
if (isJscadCadModelGroupTranslucent(cadModelGroup)) {
|
|
37
|
+
attributes.push("showAsTranslucentModel")
|
|
38
|
+
}
|
|
39
|
+
const childModelElementsTsx = generateCadModelGroupChildrenTsx({
|
|
40
|
+
cadModelGroup,
|
|
41
|
+
pcbBoard,
|
|
42
|
+
})
|
|
43
|
+
if (childModelElementsTsx.length === 0) {
|
|
44
|
+
return `<chip ${attributes.join(" ")} />`
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return `<chip ${attributes.join(" ")}>${childModelElementsTsx.join("\n")}</chip>`
|
|
33
48
|
}
|