Skip to content

Commit ac9d893

Browse files
committed
✨ feat: add loft
1 parent f7e2ba7 commit ac9d893

File tree

20 files changed

+276
-274
lines changed

20 files changed

+276
-274
lines changed

cpp/src/factory.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <BRepOffsetAPI_MakePipe.hxx>
2323
#include <BRepOffsetAPI_MakePipeShell.hxx>
2424
#include <BRepOffsetAPI_MakeThickSolid.hxx>
25+
#include <BRepOffsetAPI_ThruSections.hxx>
2526
#include <BRepPrimAPI_MakeBox.hxx>
2627
#include <BRepPrimAPI_MakeCone.hxx>
2728
#include <BRepPrimAPI_MakeCylinder.hxx>
@@ -529,6 +530,35 @@ class ShapeFactory {
529530
return ShapeResult { makeChamfer.Shape(), true, "" };
530531
}
531532

533+
static ShapeResult loft(const ShapeArray& sections, bool isSolid, bool isRuled, GeomAbs_Shape continuity)
534+
{
535+
std::vector<TopoDS_Shape> shapeVector = emscripten::vecFromJSArray<TopoDS_Shape>(sections);
536+
if (shapeVector.size() < 2) {
537+
return ShapeResult { TopoDS_Shape(), false, "Failed to loft: at least 2 sections are required" };
538+
}
539+
if (shapeVector.size() == 2 && shapeVector[0].ShapeType() == TopAbs_VERTEX && shapeVector[1].ShapeType() == TopAbs_VERTEX) {
540+
return ShapeResult { TopoDS_Shape(), false, "Failed to loft: must have at least 1 wires" };
541+
}
542+
543+
BRepOffsetAPI_ThruSections loftBuilder(isSolid, isRuled);
544+
if (!isRuled) {
545+
loftBuilder.SetContinuity(continuity);
546+
}
547+
548+
for (auto& profile : shapeVector) {
549+
if (profile.ShapeType() == TopAbs_WIRE) {
550+
loftBuilder.AddWire(TopoDS::Wire(profile));
551+
} else if (profile.ShapeType() == TopAbs_VERTEX) {
552+
loftBuilder.AddVertex(TopoDS::Vertex(profile));
553+
}
554+
}
555+
loftBuilder.Build();
556+
if (!loftBuilder.IsDone()) {
557+
return ShapeResult { TopoDS_Shape(), false, "Failed to loft" };
558+
}
559+
return ShapeResult { loftBuilder.Shape(), true, "" };
560+
}
561+
532562
static ShapeResult curveProjection(const TopoDS_Shape& curve, const TopoDS_Shape& targetFace, const gp_Dir& dir)
533563
{
534564
BRepProj_Projection curveProjection(curve, targetFace, dir);
@@ -577,5 +607,6 @@ EMSCRIPTEN_BINDINGS(ShapeFactory)
577607
.class_function("combine", &ShapeFactory::combine)
578608
.class_function("fillet", &ShapeFactory::fillet)
579609
.class_function("chamfer", &ShapeFactory::chamfer)
610+
.class_function("loft", &ShapeFactory::loft)
580611
.class_function("curveProjection", &ShapeFactory::curveProjection);
581612
}

packages/chili-builder/src/ribbon.ts

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ export const DefaultRibbon: RibbonTab[] = [
1111
groupName: "ribbon.group.draw",
1212
items: [
1313
"create.line",
14-
"create.arc",
15-
"create.rect",
16-
"create.circle",
14+
"create.extrude",
15+
["create.arc", "create.rect", "create.circle"],
16+
["create.loft", "create.sweep", "create.revol"],
1717
["create.ellipse", "create.bezier", "create.polygon"],
1818
["create.box", "create.pyramid", "create.cylinder"],
1919
["create.cone", "create.sphere", "create.thickSolid"],
@@ -23,9 +23,7 @@ export const DefaultRibbon: RibbonTab[] = [
2323
groupName: "ribbon.group.modify",
2424
items: [
2525
"modify.move",
26-
"modify.rotate",
27-
"modify.mirror",
28-
"modify.array",
26+
["modify.rotate", "modify.mirror", "modify.array"],
2927
["modify.split", "modify.break", "modify.trim"],
3028
["modify.fillet", "modify.chamfer", "modify.explode"],
3129
["modify.deleteNode", "modify.removeShapes", "modify.removeFeature"],
@@ -34,14 +32,7 @@ export const DefaultRibbon: RibbonTab[] = [
3432
},
3533
{
3634
groupName: "ribbon.group.converter",
37-
items: [
38-
"create.extrude",
39-
"convert.sweep",
40-
"convert.revol",
41-
"convert.toWire",
42-
"convert.curveProjection",
43-
["convert.toFace", "convert.toShell", "convert.toSolid"],
44-
],
35+
items: ["convert.toWire", ["convert.toFace", "convert.toShell", "convert.toSolid"]],
4536
},
4637
{
4738
groupName: "ribbon.group.boolean",
@@ -56,7 +47,11 @@ export const DefaultRibbon: RibbonTab[] = [
5647
},
5748
{
5849
groupName: "ribbon.group.tools",
59-
items: ["create.group", ["create.section", "create.offset", "create.copyShape"]],
50+
items: [
51+
"convert.curveProjection",
52+
"create.group",
53+
["create.section", "create.offset", "create.copyShape"],
54+
],
6055
},
6156
{
6257
groupName: "ribbon.group.measure",

packages/chili-core/src/i18n/en.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ export default {
5050
"command.boolean.cut": "Cut",
5151
"command.boolean.join": "Join",
5252
"command.convert.fuse": "Fuse",
53-
"command.convert.revol": "Revolve",
54-
"command.convert.sweep": "Sweep",
53+
"command.create.revol": "Revolve",
54+
"command.create.sweep": "Sweep",
5555
"command.convert.toFace": "To Face",
5656
"command.convert.toShell": "To Shell",
5757
"command.convert.toSolid": "To Solid",
@@ -70,6 +70,7 @@ export default {
7070
"command.create.folder": "Folder",
7171
"command.create.group": "Group",
7272
"command.create.line": "Line",
73+
"command.create.loft": "Loft",
7374
"command.create.offset": "Offset",
7475
"command.create.polygon": "Pline",
7576
"command.create.pyramid": "Pyramid",
@@ -181,9 +182,12 @@ export default {
181182
"material.metalnessMap": "Metalness Map",
182183
"material.roughness": "Roughness",
183184
"model.visible": "Visible",
185+
"option.command.continuity": "Continuity",
184186
"option.command.circularPattern": "Circular Pattern",
185187
"option.command.repeat": "Repeat",
186188
"option.command.isFace": "Face",
189+
"option.command.isSolid": "Solid",
190+
"option.command.isRuled": "Ruled",
187191
"option.command.isRoundCorner": "Round Corner",
188192
"option.command.thickness": "Thickness",
189193
"option.command.isConnected": "Connected",

packages/chili-core/src/i18n/keys.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ const I18N_KEYS = [
4545
"command.boolean.cut",
4646
"command.boolean.join",
4747
"command.convert.fuse",
48-
"command.convert.revol",
49-
"command.convert.sweep",
48+
"command.create.revol",
49+
"command.create.sweep",
5050
"command.convert.toFace",
5151
"command.convert.toShell",
5252
"command.convert.toSolid",
@@ -65,6 +65,7 @@ const I18N_KEYS = [
6565
"command.create.folder",
6666
"command.create.group",
6767
"command.create.line",
68+
"command.create.loft",
6869
"command.create.offset",
6970
"command.create.polygon",
7071
"command.create.pyramid",
@@ -181,8 +182,11 @@ const I18N_KEYS = [
181182
"prompt.pickNextPoint",
182183
"prompt.pickRadius",
183184
"option.command.circularPattern",
185+
"option.command.continuity",
184186
"option.command.repeat",
185187
"option.command.isFace",
188+
"option.command.isSolid",
189+
"option.command.isRuled",
186190
"option.command.isRoundCorner",
187191
"option.command.thickness",
188192
"option.command.isConnected",

0 commit comments

Comments
 (0)