Skip to content

Commit 83a58cd

Browse files
committed
Part: support element mapping in all c++ features
1 parent d3a1241 commit 83a58cd

24 files changed

+597
-94
lines changed

src/Mod/Part/App/CrossSection.cpp

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#endif
4646

4747
#include "CrossSection.h"
48+
#include "TopoShapeOpCode.h"
4849

4950
using namespace Part;
5051

@@ -199,3 +200,97 @@ void CrossSection::connectWires (const TopTools_IndexedMapOfShape& wireMap, std:
199200
wires.push_back(aFix.Wire());
200201
}
201202
}
203+
204+
///////////////////////////////////////////////////////////////////////////
205+
TopoCrossSection::TopoCrossSection(double a, double b, double c, const TopoShape& s, const char *op)
206+
: a(a), b(b), c(c), shape(s), op(op?op:TOPOP_SLICE)
207+
{
208+
}
209+
210+
void TopoCrossSection::slice(int idx, double d, std::vector<TopoShape> &wires) const {
211+
// Fixes: 0001228: Cross section of Torus in Part Workbench fails or give wrong results
212+
// Fixes: 0001137: Incomplete slices when using Part.slice on a torus
213+
bool found = false;
214+
for(auto &s : shape.getSubTopoShapes(TopAbs_SOLID)) {
215+
sliceSolid(idx, d, s, wires);
216+
found = true;
217+
}
218+
if(!found) {
219+
for(auto &s : shape.getSubTopoShapes(TopAbs_SHELL)) {
220+
sliceSolid(idx, d, s, wires);
221+
found = true;
222+
}
223+
if(!found) {
224+
for(auto &s : shape.getSubTopoShapes(TopAbs_FACE))
225+
sliceSolid(idx, d, s, wires);
226+
}
227+
}
228+
}
229+
230+
TopoShape TopoCrossSection::slice(int idx, double d) const {
231+
std::vector<TopoShape> wires;
232+
slice(idx,d,wires);
233+
return TopoShape().makECompound(wires,false,0,false);
234+
}
235+
236+
void TopoCrossSection::sliceNonSolid(int idx, double d,
237+
const TopoShape& shape, std::vector<TopoShape>& wires) const
238+
{
239+
BRepAlgoAPI_Section cs(shape.getShape(), gp_Pln(a,b,c,-d));
240+
if (cs.IsDone()) {
241+
std::string prefix(op);
242+
if(idx>1) {
243+
prefix += '_';
244+
prefix += std::to_string(idx);
245+
}
246+
auto res = TopoShape().makEShape(cs,shape,prefix.c_str()).makEWires().getSubTopoShapes(TopAbs_WIRE);
247+
wires.insert(wires.end(),res.begin(),res.end());
248+
}
249+
}
250+
251+
void TopoCrossSection::sliceSolid(int idx, double d,
252+
const TopoShape& shape, std::vector<TopoShape>& wires) const
253+
{
254+
gp_Pln slicePlane(a,b,c,-d);
255+
BRepBuilderAPI_MakeFace mkFace(slicePlane);
256+
TopoShape face(idx);
257+
face.setShape(mkFace.Face());
258+
259+
// Make sure to choose a point that does not lie on the plane (fixes #0001228)
260+
gp_Vec tempVector(a,b,c);
261+
tempVector.Normalize();//just in case.
262+
tempVector *= (d+1.0);
263+
gp_Pnt refPoint(0.0, 0.0, 0.0);
264+
refPoint.Translate(tempVector);
265+
266+
BRepPrimAPI_MakeHalfSpace mkSolid(TopoDS::Face(face.getShape()), refPoint);
267+
TopoShape solid(idx);
268+
std::string prefix(op);
269+
if(idx>1) {
270+
prefix += '_';
271+
prefix += std::to_string(idx);
272+
}
273+
solid.makEShape(mkSolid,face,prefix.c_str());
274+
BRepAlgoAPI_Cut mkCut(shape.getShape(), solid.getShape());
275+
276+
if (mkCut.IsDone()) {
277+
TopoShape res(shape.Tag,shape.Hasher);
278+
std::vector<TopoShape> shapes;
279+
shapes.push_back(shape);
280+
shapes.push_back(solid);
281+
res.makEShape(mkCut,shapes,prefix.c_str());
282+
for(auto &face : res.getSubTopoShapes(TopAbs_FACE)) {
283+
BRepAdaptor_Surface adapt(TopoDS::Face(face.getShape()));
284+
if (adapt.GetType() == GeomAbs_Plane) {
285+
gp_Pln plane = adapt.Plane();
286+
if (plane.Axis().IsParallel(slicePlane.Axis(), Precision::Confusion()) &&
287+
plane.Distance(slicePlane.Location()) < Precision::Confusion()) {
288+
auto repaired_wires = TopoShape(face.Tag).makEWires(
289+
face.getSubTopoShapes(TopAbs_EDGE),prefix.c_str(),true).getSubTopoShapes(TopAbs_WIRE);
290+
wires.insert(wires.end(),repaired_wires.begin(),repaired_wires.end());
291+
}
292+
}
293+
}
294+
}
295+
}
296+

src/Mod/Part/App/CrossSection.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
#define PART_CROSSSECTION_H
2626

2727
#include <list>
28+
#include <vector>
2829
#include <TopTools_IndexedMapOfShape.hxx>
30+
#include "TopoShape.h"
2931

3032
class TopoDS_Shape;
3133
class TopoDS_Wire;
@@ -49,6 +51,23 @@ class PartExport CrossSection
4951
const TopoDS_Shape& s;
5052
};
5153

54+
class PartExport TopoCrossSection
55+
{
56+
public:
57+
TopoCrossSection(double a, double b, double c, const TopoShape& s, const char *op=0);
58+
void slice(int idx, double d, std::vector<TopoShape> &wires) const;
59+
TopoShape slice(int idx, double d) const;
60+
61+
private:
62+
void sliceNonSolid(int idx, double d, const TopoShape&, std::vector<TopoShape>& wires) const;
63+
void sliceSolid(int idx, double d, const TopoShape&, std::vector<TopoShape>& wires) const;
64+
65+
private:
66+
double a,b,c;
67+
const TopoShape& shape;
68+
const char *op;
69+
};
70+
5271
}
5372

5473
#endif // PART_CROSSSECTION_H

src/Mod/Part/App/FeatureChamfer.cpp

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#endif
3535

3636

37+
#include <App/Document.h>
38+
#include "TopoShapeOpCode.h"
3739
#include "FeatureChamfer.h"
3840

3941

@@ -53,11 +55,15 @@ App::DocumentObjectExecReturn *Chamfer::execute(void)
5355
return new App::DocumentObjectExecReturn("No object linked");
5456

5557
try {
56-
TopoDS_Shape baseShape = Feature::getShape(link);
58+
TopoShape baseTopoShape = Feature::getTopoShape(link);
59+
auto baseShape = baseTopoShape.getShape();
5760
BRepFilletAPI_MakeChamfer mkChamfer(baseShape);
58-
TopTools_IndexedMapOfShape mapOfEdges;
5961
TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace;
6062
TopExp::MapShapesAndAncestors(baseShape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace);
63+
64+
65+
#ifdef FC_NO_ELEMENT_MAP
66+
TopTools_IndexedMapOfShape mapOfEdges;
6167
TopExp::MapShapes(baseShape, TopAbs_EDGE, mapOfEdges);
6268

6369
std::vector<FilletElement> values = Edges.getValues();
@@ -73,7 +79,7 @@ App::DocumentObjectExecReturn *Chamfer::execute(void)
7379
TopoDS_Shape shape = mkChamfer.Shape();
7480
if (shape.IsNull())
7581
return new App::DocumentObjectExecReturn("Resulting shape is null");
76-
ShapeHistory history(mkChamfer, TopAbs_FACE, shape, baseShape);
82+
ShapeHistory history(mkFillet, TopAbs_FACE, shape, baseTopoShape);
7783
this->Shape.setValue(shape);
7884

7985
// make sure the 'PropertyShapeHistory' is not safed in undo/redo (#0001889)
@@ -82,6 +88,36 @@ App::DocumentObjectExecReturn *Chamfer::execute(void)
8288
prop.setContainer(this);
8389
prop.touch();
8490

91+
#else
92+
const auto &vals = EdgeLinks.getSubValues();
93+
const auto &subs = EdgeLinks.getShadowSubs();
94+
if(subs.size()!=(size_t)Edges.getSize())
95+
return new App::DocumentObjectExecReturn("Edge link size mismatch");
96+
size_t i=0;
97+
for(const auto &info : Edges.getValues()) {
98+
auto &sub = subs[i];
99+
auto &ref = sub.first.size()?sub.first:vals[i];
100+
++i;
101+
TopoDS_Shape edge;
102+
try {
103+
edge = baseTopoShape.getSubShape(ref.c_str());
104+
}catch(...){}
105+
if(edge.IsNull())
106+
return new App::DocumentObjectExecReturn("Invalid edge link");
107+
double radius1 = info.radius1;
108+
double radius2 = info.radius2;
109+
const TopoDS_Face& face = TopoDS::Face(mapEdgeFace.FindFromKey(edge).First());
110+
mkChamfer.Add(radius1, radius2, TopoDS::Edge(edge), face);
111+
}
112+
113+
TopoDS_Shape shape = mkChamfer.Shape();
114+
if (shape.IsNull())
115+
return new App::DocumentObjectExecReturn("Resulting shape is null");
116+
117+
TopoShape res(getID(),getDocument()->getStringHasher());
118+
this->Shape.setValue(res.makEShape(mkChamfer,baseTopoShape,TOPOP_CHAMFER));
119+
#endif
120+
85121
return App::DocumentObject::StdReturn;
86122
}
87123
catch (Standard_Failure& e) {

0 commit comments

Comments
 (0)