void CrossSection::connectEdges (const std::list<TopoDS_Edge>& edges, std::list<TopoDS_Wire>& wires) const { std::list<TopoDS_Edge> edge_list = edges; while (edge_list.size() > 0) { BRepBuilderAPI_MakeWire mkWire; // add and erase first edge mkWire.Add(edge_list.front()); edge_list.erase(edge_list.begin()); TopoDS_Wire new_wire = mkWire.Wire(); // current new wire // try to connect each edge to the wire, the wire is complete if no more egdes are connectible bool found = false; do { found = false; for (std::list<TopoDS_Edge>::iterator pE = edge_list.begin(); pE != edge_list.end();++pE) { mkWire.Add(*pE); if (mkWire.Error() != BRepBuilderAPI_DisconnectedWire) { // edge added ==> remove it from list found = true; edge_list.erase(pE); new_wire = mkWire.Wire(); break; } } } while (found); wires.push_back(new_wire); } }
bool SweepWidget::isPathValid(const Gui::SelectionObject& sel) const { const App::DocumentObject* path = sel.getObject(); if (!(path && path->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))) return false; const std::vector<std::string>& sub = sel.getSubNames(); TopoDS_Shape pathShape; const Part::TopoShape& shape = static_cast<const Part::Feature*>(path)->Shape.getValue(); if (!sub.empty()) { try { BRepBuilderAPI_MakeWire mkWire; for (std::vector<std::string>::const_iterator it = sub.begin(); it != sub.end(); ++it) { TopoDS_Shape subshape = shape.getSubShape(it->c_str()); mkWire.Add(TopoDS::Edge(subshape)); } pathShape = mkWire.Wire(); } catch (...) { return false; } } else if (shape._Shape.ShapeType() == TopAbs_EDGE) { pathShape = shape._Shape; } else if (shape._Shape.ShapeType() == TopAbs_WIRE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape)); pathShape = mkWire.Wire(); } return (!pathShape.IsNull()); }
//! make a clean wire with sorted, oriented, connected, etc edges TopoDS_Wire EdgeWalker::makeCleanWire(std::vector<TopoDS_Edge> edges, double tol) { TopoDS_Wire result; BRepBuilderAPI_MakeWire mkWire; ShapeFix_ShapeTolerance sTol; Handle(ShapeExtend_WireData) wireData = new ShapeExtend_WireData(); for (auto e:edges) { wireData->Add(e); } Handle(ShapeFix_Wire) fixer = new ShapeFix_Wire; fixer->Load(wireData); fixer->Perform(); fixer->FixReorder(); fixer->SetMaxTolerance(tol); fixer->ClosedWireMode() = Standard_True; fixer->FixConnected(Precision::Confusion()); fixer->FixClosed(Precision::Confusion()); for (int i = 1; i <= wireData->NbEdges(); i ++) { TopoDS_Edge edge = fixer->WireData()->Edge(i); sTol.SetTolerance(edge, tol, TopAbs_VERTEX); mkWire.Add(edge); } result = mkWire.Wire(); return result; }
static TopoDS_Wire mkWire1() { BRepBuilderAPI_MakeEdge aMkEdge1 (mkCurve2()); BRepBuilderAPI_MakeEdge aMkEdge2 (mkCurve3()); BRepBuilderAPI_MakeWire aMkWire (aMkEdge1, aMkEdge2); return aMkWire.Wire(); }
void BRepOffsetAPI_MakeOffsetFix::AddWire(const TopoDS_Wire& Spine) { TopoDS_Wire wire = Spine; int numEdges = 0; TopExp_Explorer xp(wire, TopAbs_EDGE); while (xp.More()) { numEdges++; xp.Next(); } if (numEdges == 1) { TopLoc_Location edgeLocation; BRepBuilderAPI_MakeWire mkWire; TopExp_Explorer xp(wire, TopAbs_EDGE); while (xp.More()) { // The trick is to reset the placement of an edge before // passing it to BRepOffsetAPI_MakeOffset because then it // will create the expected result. // Afterwards apply the placement again on the result shape. // See the method MakeWire() TopoDS_Edge edge = TopoDS::Edge(xp.Current()); edgeLocation = edge.Location(); edge.Location(TopLoc_Location()); mkWire.Add(edge); myLocations.push_back(std::make_pair(edge, edgeLocation)); xp.Next(); } wire = mkWire.Wire(); } mkOffset.AddWire(wire); myResult.Nullify(); }
bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face) { TopoDS_Vertex* vertices = new TopoDS_Vertex[numVerts]; for ( int i = 0; i < numVerts; i ++ ) { gp_XY xy (verts[2*i],verts[2*i+1]); trsf.Transforms(xy); vertices[i] = BRepBuilderAPI_MakeVertex(gp_Pnt(xy.X(),xy.Y(),0.0f)); } BRepBuilderAPI_MakeWire w; for ( int i = 0; i < numVerts; i ++ ) w.Add(BRepBuilderAPI_MakeEdge(vertices[i],vertices[(i+1)%numVerts])); IfcGeom::convert_wire_to_face(w.Wire(),face); if ( numFillets && *std::max_element(filletRadii, filletRadii + numFillets) > 1e-7 ) { BRepFilletAPI_MakeFillet2d fillet (face); for ( int i = 0; i < numFillets; i ++ ) { const double radius = filletRadii[i]; if ( radius <= 1e-7 ) continue; fillet.AddFillet(vertices[filletIndices[i]],radius); } fillet.Build(); if (fillet.IsDone()) { face = TopoDS::Face(fillet.Shape()); } else { Logger::Message(Logger::LOG_WARNING, "Failed to process profile fillets"); } } delete[] vertices; return true; }
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCircleHollowProfileDef* l, TopoDS_Shape& face) { const double r = l->Radius() * getValue(GV_LENGTH_UNIT); const double t = l->WallThickness() * getValue(GV_LENGTH_UNIT); if ( r == 0.0f || t == 0.0f ) { Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity); return false; } gp_Trsf2d trsf2d; bool has_position = true; #ifdef USE_IFC4 has_position = l->hasPosition(); #endif if (has_position) { IfcGeom::Kernel::convert(l->Position(), trsf2d); } gp_Ax2 ax = gp_Ax2().Transformed(trsf2d); BRepBuilderAPI_MakeWire outer; Handle(Geom_Circle) outerCircle = new Geom_Circle(ax, r); outer.Add(BRepBuilderAPI_MakeEdge(outerCircle)); BRepBuilderAPI_MakeFace mf(outer.Wire(), false); BRepBuilderAPI_MakeWire inner; Handle(Geom_Circle) innerCirlce = new Geom_Circle(ax, r-t); inner.Add(BRepBuilderAPI_MakeEdge(innerCirlce)); mf.Add(inner); ShapeFix_Shape sfs(mf.Face()); sfs.Perform(); face = TopoDS::Face(sfs.Shape()); return true; }
bool IfcGeom::Kernel::convert(const IfcSchema::IfcEdge* l, TopoDS_Wire& result) { if (!l->EdgeStart()->is(IfcSchema::Type::IfcVertexPoint) || !l->EdgeEnd()->is(IfcSchema::Type::IfcVertexPoint)) { Logger::Message(Logger::LOG_ERROR, "Only IfcVertexPoints are supported for EdgeStart and -End", l->entity); return false; } IfcSchema::IfcPoint* pnt1 = ((IfcSchema::IfcVertexPoint*) l->EdgeStart())->VertexGeometry(); IfcSchema::IfcPoint* pnt2 = ((IfcSchema::IfcVertexPoint*) l->EdgeEnd())->VertexGeometry(); if (!pnt1->is(IfcSchema::Type::IfcCartesianPoint) || !pnt2->is(IfcSchema::Type::IfcCartesianPoint)) { Logger::Message(Logger::LOG_ERROR, "Only IfcCartesianPoints are supported for VertexGeometry", l->entity); return false; } gp_Pnt p1, p2; if (!convert(((IfcSchema::IfcCartesianPoint*)pnt1), p1) || !convert(((IfcSchema::IfcCartesianPoint*)pnt2), p2)) { return false; } BRepBuilderAPI_MakeWire mw; mw.Add(BRepBuilderAPI_MakeEdge(p1, p2)); result = mw.Wire(); return true; }
void BRepOffsetAPI_MakeOffsetFix::MakeWire(TopoDS_Shape& wire) { // get the edges of the wire and check which of the stored edges // serve as input of the wire TopTools_MapOfShape aMap; TopExp_Explorer xp(wire, TopAbs_EDGE); while (xp.More()) { aMap.Add(xp.Current()); xp.Next(); } std::list<TopoDS_Edge> edgeList; for (auto itLoc : myLocations) { const TopTools_ListOfShape& newShapes = mkOffset.Generated(itLoc.first); for (TopTools_ListIteratorOfListOfShape it(newShapes); it.More(); it.Next()) { TopoDS_Shape newShape = it.Value(); if (aMap.Contains(newShape)) { newShape.Move(itLoc.second); edgeList.push_back(TopoDS::Edge(newShape)); } } } if (!edgeList.empty()) { BRepBuilderAPI_MakeWire mkWire; mkWire.Add(edgeList.front()); edgeList.pop_front(); wire = mkWire.Wire(); bool found = false; do { found = false; for (std::list<TopoDS_Edge>::iterator pE = edgeList.begin(); pE != edgeList.end(); ++pE) { mkWire.Add(*pE); if (mkWire.Error() != BRepBuilderAPI_DisconnectedWire) { // edge added ==> remove it from list found = true; edgeList.erase(pE); wire = mkWire.Wire(); break; } } } while (found); } }
bool SweepWidget::isPathValid(const Gui::SelectionObject& sel) const { const App::DocumentObject* path = sel.getObject(); if (!(path && path->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))) return false; const std::vector<std::string>& sub = sel.getSubNames(); TopoDS_Shape pathShape; const Part::TopoShape& shape = static_cast<const Part::Feature*>(path)->Shape.getValue(); if (!sub.empty()) { try { BRepBuilderAPI_MakeWire mkWire; for (std::vector<std::string>::const_iterator it = sub.begin(); it != sub.end(); ++it) { TopoDS_Shape subshape = shape.getSubShape(it->c_str()); mkWire.Add(TopoDS::Edge(subshape)); } pathShape = mkWire.Wire(); } catch (...) { return false; } } else if (shape._Shape.ShapeType() == TopAbs_EDGE) { pathShape = shape._Shape; } else if (shape._Shape.ShapeType() == TopAbs_WIRE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape)); pathShape = mkWire.Wire(); } else if (shape._Shape.ShapeType() == TopAbs_COMPOUND) { try { TopoDS_Iterator it(shape._Shape); for (; it.More(); it.Next()) { if ((it.Value().ShapeType() != TopAbs_EDGE) && (it.Value().ShapeType() != TopAbs_WIRE)) { return false; } } Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape(); Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape(); for (TopExp_Explorer xp(shape._Shape, TopAbs_EDGE); xp.More(); xp.Next()) hEdges->Append(xp.Current()); ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_True, hWires); int len = hWires->Length(); if (len != 1) return false; pathShape = hWires->Value(1); } catch (...) { return false; } } return (!pathShape.IsNull()); }
static TopoDS_Wire mkWire9() { Standard_Real aCoords[][3] = { {0,-1,0},{0,-2,2},{0,0,1},{0,2,2},{0,1,0},{0,2,-2},{0,0,-1},{0,-2,-2} }; Standard_Integer nPoles = sizeof(aCoords)/(sizeof(Standard_Real)*3); Handle(Geom_Curve) aCurve = mkPBSplineCurve (nPoles, aCoords); BRepBuilderAPI_MakeEdge aMkEdge (aCurve); BRepBuilderAPI_MakeWire aMkWire (aMkEdge); return aMkWire.Wire(); }
TopoDS_Shape OCCPartFactory::makeCube( const Standard_Real width, const Standard_Real height, const Standard_Real depth) { // define points gp_Pnt pt1( -width / 2.0, 0.0, 0.0 ); gp_Pnt pt2( -width / 2.0, -depth / 2.0, 0.0 ); gp_Pnt pt3( width / 2.0, -depth / 2.0, 0.0 ); gp_Pnt pt4( width /2.0, 0.0, 0.0 ); // define segments Handle_Geom_TrimmedCurve seg1 = GC_MakeSegment( pt1, pt2 ); Handle_Geom_TrimmedCurve seg2 = GC_MakeSegment( pt2, pt3 ); Handle_Geom_TrimmedCurve seg3 = GC_MakeSegment( pt3, pt4 ); // make edge TopoDS_Edge edge1 = BRepBuilderAPI_MakeEdge( seg1 ); TopoDS_Edge edge2 = BRepBuilderAPI_MakeEdge( seg2 ); TopoDS_Edge edge3 = BRepBuilderAPI_MakeEdge( seg3 ); // make wire TopoDS_Wire wire1 = BRepBuilderAPI_MakeWire( edge1, edge2, edge3 ); //Complete Profile gp_Ax1 xAxis = gp::OX(); gp_Trsf transfer; transfer.SetMirror( xAxis ); BRepBuilderAPI_Transform aBRepTrsf( wire1 , transfer ); TopoDS_Shape mirroredShape = aBRepTrsf.Shape(); TopoDS_Wire mirroredWire1 = TopoDS::Wire( mirroredShape ); BRepBuilderAPI_MakeWire mkWire; mkWire.Add( wire1 ); mkWire.Add( mirroredWire1 ); TopoDS_Wire wireProfile = mkWire.Wire(); //Body : Prism the Profile TopoDS_Face faceProfile = BRepBuilderAPI_MakeFace( wireProfile ); gp_Vec prismVec( 0.0 , 0.0 , height ); TopoDS_Shape cube = BRepPrimAPI_MakePrism( faceProfile, prismVec); // cube.setMaterial( Graphic3d_NOM_JADE ); // Handle_AIS_Shape shape = new AIS_Shape( cube ); // shape->SetColor( Quantity_NOC_RED ); // return shape; return cube; }
TopoDS_Wire CCPACSWingProfile::GetWire() { Update(); // rebuild closed wire BRepBuilderAPI_MakeWire closedWireBuilder; closedWireBuilder.Add(profileAlgo->GetUpperLowerWire()); if (!profileAlgo->GetTrailingEdge().IsNull()) { closedWireBuilder.Add(profileAlgo->GetTrailingEdge()); } return closedWireBuilder.Wire(); }
void Pipe::buildPipePath(const Part::TopoShape& shape, const std::vector< std::string >& subedge, TopoDS_Shape& path) { if (!shape._Shape.IsNull()) { try { if (!subedge.empty()) { //if(SpineTangent.getValue()) //getContiniusEdges(shape, subedge); BRepBuilderAPI_MakeWire mkWire; for (std::vector<std::string>::const_iterator it = subedge.begin(); it != subedge.end(); ++it) { TopoDS_Shape subshape = shape.getSubShape(it->c_str()); mkWire.Add(TopoDS::Edge(subshape)); } path = mkWire.Wire(); } else if (shape._Shape.ShapeType() == TopAbs_EDGE) { path = shape._Shape; } else if (shape._Shape.ShapeType() == TopAbs_WIRE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape)); path = mkWire.Wire(); } else if (shape._Shape.ShapeType() == TopAbs_COMPOUND) { TopoDS_Iterator it(shape._Shape); for (; it.More(); it.Next()) { if (it.Value().IsNull()) throw Base::Exception("In valid element in spine."); if ((it.Value().ShapeType() != TopAbs_EDGE) && (it.Value().ShapeType() != TopAbs_WIRE)) { throw Base::Exception("Element in spine is neither an edge nor a wire."); } } Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape(); Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape(); for (TopExp_Explorer xp(shape._Shape, TopAbs_EDGE); xp.More(); xp.Next()) hEdges->Append(xp.Current()); ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_True, hWires); int len = hWires->Length(); if (len != 1) throw Base::Exception("Spine is not connected."); path = hWires->Value(1); } else { throw Base::Exception("Spine is neither an edge nor a wire."); } } catch (Standard_Failure) { throw Base::Exception("Invalid spine."); } } }
static TopoDS_Wire mkWire3() { BRepBuilderAPI_MakeEdge aMkEdge1 (mkCurve1()); Standard_Real aCoords[][3] = { {0,10,20},{0,20,10},{0,20,0},{0,0,0} }; Standard_Integer nPoles = sizeof(aCoords)/(sizeof(Standard_Real)*3); Handle(Geom_Curve) aCurve = mkBezierCurve (nPoles, aCoords); BRepBuilderAPI_MakeEdge aMkEdge2 (aCurve); BRepBuilderAPI_MakeWire aMkWire (aMkEdge1, aMkEdge2); return aMkWire.Wire(); }
// Make a TopoDS_Wire from a list of TopoDS_Edges TopoDS_Wire edgesToWire(std::vector<TopoDS_Edge> Edges) { TopoDS_Wire occwire; std::vector<TopoDS_Edge>::iterator iEdge; BRepBuilderAPI_MakeWire mkWire; for (iEdge = Edges.begin(); iEdge != Edges.end(); ++iEdge){ mkWire.Add(*iEdge); if (!mkWire.IsDone()) { Base::Console().Message("FT2FC Trace edgesToWire failed to add wire\n"); } } occwire = mkWire.Wire(); BRepLib::BuildCurves3d(occwire); return(occwire); }
bool IfcGeom::convert(const Ifc2x3::IfcPolyline::ptr l, TopoDS_Wire& result) { Ifc2x3::IfcCartesianPoint::list points = l->Points(); BRepBuilderAPI_MakeWire w; gp_Pnt P1;gp_Pnt P2; for( Ifc2x3::IfcCartesianPoint::it it = points->begin(); it != points->end(); ++ it ) { IfcGeom::convert(*it,P2); if ( it != points->begin() && ( !P1.IsEqual(P2,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) ) w.Add(BRepBuilderAPI_MakeEdge(P1,P2)); P1 = P2; } result = w.Wire(); return true; }
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCenterLineProfileDef* l, TopoDS_Shape& face) { const double d = l->Thickness() * getValue(GV_LENGTH_UNIT) / 2.; TopoDS_Wire wire; if (!convert_wire(l->Curve(), wire)) return false; // BRepOffsetAPI_MakeOffset insists on creating circular arc // segments for joining the curves that constitute the center // line. This is probably not in accordance with the IFC spec. // Although it does not specify a method to join segments // explicitly, it does dictate 'a constant thickness along the // curve'. Therefore for simple singular wires a quick // alternative is provided that uses a straight join. TopExp_Explorer exp(wire, TopAbs_EDGE); TopoDS_Edge edge = TopoDS::Edge(exp.Current()); exp.Next(); if (!exp.More()) { double u1, u2; Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, u1, u2); Handle(Geom_TrimmedCurve) trim = new Geom_TrimmedCurve(curve, u1, u2); Handle(Geom_OffsetCurve) c1 = new Geom_OffsetCurve(trim, d, gp::DZ()); Handle(Geom_OffsetCurve) c2 = new Geom_OffsetCurve(trim, -d, gp::DZ()); gp_Pnt c1a, c1b, c2a, c2b; c1->D0(c1->FirstParameter(), c1a); c1->D0(c1->LastParameter(), c1b); c2->D0(c2->FirstParameter(), c2a); c2->D0(c2->LastParameter(), c2b); BRepBuilderAPI_MakeWire mw; mw.Add(BRepBuilderAPI_MakeEdge(c1)); mw.Add(BRepBuilderAPI_MakeEdge(c1a, c2a)); mw.Add(BRepBuilderAPI_MakeEdge(c2)); mw.Add(BRepBuilderAPI_MakeEdge(c2b, c1b)); face = BRepBuilderAPI_MakeFace(mw.Wire()); } else { BRepOffsetAPI_MakeOffset offset(BRepBuilderAPI_MakeFace(gp_Pln(gp::Origin(), gp::DZ()))); offset.AddWire(wire); offset.Perform(d); face = BRepBuilderAPI_MakeFace(TopoDS::Wire(offset)); } return true; }
int OCCWire::createWire(std::vector<OCCEdge *> edges) { try { BRepBuilderAPI_MakeWire MW; for (unsigned i=0; i<edges.size(); i++) { OCCEdge *edge = edges[i]; MW.Add(edge->getEdge()); } BRepBuilderAPI_WireError error = MW.Error(); switch (error) { case BRepBuilderAPI_EmptyWire: { StdFail_NotDone::Raise("Wire empty"); break; } case BRepBuilderAPI_DisconnectedWire: { StdFail_NotDone::Raise("Disconnected wire"); break; } case BRepBuilderAPI_NonManifoldWire : { StdFail_NotDone::Raise("non-manifold wire"); break; } } this->setShape(MW.Wire()); // possible fix shape if (!this->fixShape()) StdFail_NotDone::Raise("Shapes not valid"); } catch(Standard_Failure &err) { Handle_Standard_Failure e = Standard_Failure::Caught(); const Standard_CString msg = e->GetMessageString(); if (msg != NULL && strlen(msg) > 1) { setErrorMessage(msg); } else { setErrorMessage("Failed to create wire"); } return 0; } return 1; }
bool IfcGeom::Kernel::convert(const IfcSchema::IfcSubedge* l, TopoDS_Wire& result) { TopoDS_Wire temp; if (convert_wire(l->ParentEdge(), result) && convert((IfcSchema::IfcEdge*) l, temp)) { TopExp_Explorer exp(result, TopAbs_EDGE); TopoDS_Edge edge = TopoDS::Edge(exp.Current()); Standard_Real u1, u2; Handle(Geom_Curve) crv = BRep_Tool::Curve(edge, u1, u2); TopoDS_Vertex v1, v2; TopExp::Vertices(temp, v1, v2); BRepBuilderAPI_MakeWire mw; mw.Add(BRepBuilderAPI_MakeEdge(crv, v1, v2)); result = mw.Wire(); return true; } else { return false; } }
// Returns the wing profile lower and upper wire fused TopoDS_Wire CCPACSWingProfile::GetSplitWire() { Update(); // rebuild closed wire BRepBuilderAPI_MakeWire closedWireBuilder; closedWireBuilder.Add(profileAlgo->GetLowerWire()); closedWireBuilder.Add(profileAlgo->GetUpperWire()); if (!profileAlgo->GetTrailingEdge().IsNull()) { closedWireBuilder.Add(profileAlgo->GetTrailingEdge()); } closedWireBuilder.Build(); if (!closedWireBuilder.IsDone()) { throw CTiglError("Error creating closed wing profile"); } return closedWireBuilder.Wire(); }
App::DocumentObjectExecReturn *Torus::execute(void) { if (Radius1.getValue() < Precision::Confusion()) return new App::DocumentObjectExecReturn("Radius of torus too small"); if (Radius2.getValue() < Precision::Confusion()) return new App::DocumentObjectExecReturn("Radius of torus too small"); try { #if 1 // Build a torus gp_Circ circle; circle.SetRadius(Radius2.getValue()); gp_Pnt pos(Radius1.getValue(),0,0); gp_Dir dir(0,1,0); circle.SetAxis(gp_Ax1(pos, dir)); BRepBuilderAPI_MakeEdge mkEdge(circle, Base::toRadians<double>(Angle1.getValue()+180.0f), Base::toRadians<double>(Angle2.getValue()+180.0f)); BRepBuilderAPI_MakeWire mkWire; mkWire.Add(mkEdge.Edge()); BRepBuilderAPI_MakeFace mkFace(mkWire.Wire()); BRepPrimAPI_MakeRevol mkRevol(mkFace.Face(), gp_Ax1(gp_Pnt(0,0,0), gp_Dir(0,0,1)), Base::toRadians<double>(Angle3.getValue()), Standard_True); TopoDS_Shape ResultShape = mkRevol.Shape(); #else BRepPrimAPI_MakeTorus mkTorus(Radius1.getValue(), Radius2.getValue(), Angle1.getValue()/180.0f*Standard_PI, Angle2.getValue()/180.0f*Standard_PI, Angle3.getValue()/180.0f*Standard_PI); const TopoDS_Solid& ResultShape = mkTorus.Solid(); #endif this->Shape.setValue(ResultShape); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); return new App::DocumentObjectExecReturn(e->GetMessageString()); } return App::DocumentObject::StdReturn; }
TopoDS_Shape MakeBottle(const Standard_Real myWidth, const Standard_Real myHeight, const Standard_Real myThickness) { BRepBuilderAPI_MakeWire wireMaker; // Profile : Define Support Points { Handle(TColgp_HArray1OfPnt) gp_array = new TColgp_HArray1OfPnt(1, 4); gp_Pnt p0(-myWidth / 2., 0, 0); gp_Pnt p4(myWidth / 2., 0, 0); // gp_array->SetValue(0, p0); gp_array->SetValue(1, gp_Pnt(-myWidth / 2., -myThickness / 4., 0)); gp_array->SetValue(2, gp_Pnt(0, -myThickness / 2., 0)); gp_array->SetValue(3, gp_Pnt(myWidth / 2., -myThickness / 4., 0)); gp_array->SetValue(4, p4); GeomAPI_Interpolate sp(gp_array, true, 1.0e-3); sp.Perform(); wireMaker.Add(BRepBuilderAPI_MakeEdge(sp.Curve())); } // Body : Prism the Profile TopoDS_Face myFaceProfile = BRepBuilderAPI_MakeFace(wireMaker.Wire()); gp_Vec aPrismVec(0, 0, myHeight); TopoDS_Shape myBody = BRepPrimAPI_MakePrism(myFaceProfile, aPrismVec); // Building the Resulting Compound TopoDS_Compound aRes; BRep_Builder aBuilder; aBuilder.MakeCompound(aRes); aBuilder.Add(aRes, myBody); // aBuilder.Add(aRes, myThreading); return aRes; }
bool IfcGeom::convert(const Ifc2x3::IfcPolyLoop::ptr l, TopoDS_Wire& result) { Ifc2x3::IfcCartesianPoint::list points = l->Polygon(); BRepBuilderAPI_MakeWire w; gp_Pnt P1;gp_Pnt P2;gp_Pnt F; int count = 0; for( Ifc2x3::IfcCartesianPoint::it it = points->begin(); it != points->end(); ++ it ) { IfcGeom::convert(*it,P2); if ( it != points->begin() && ( !P1.IsEqual(P2,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) ) { w.Add(BRepBuilderAPI_MakeEdge(P1,P2)); count ++; } else if ( ! count ) F = P2; P1 = P2; } if ( !P1.IsEqual(F,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) { w.Add(BRepBuilderAPI_MakeEdge(P1,F)); count ++; } if ( count < 3 ) return false; result = w.Wire(); return true; }
App::DocumentObjectExecReturn *Sweep::execute(void) { if (Sections.getSize() == 0) return new App::DocumentObjectExecReturn("No sections linked."); App::DocumentObject* spine = Spine.getValue(); if (!(spine && spine->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))) return new App::DocumentObjectExecReturn("No spine linked."); const std::vector<std::string>& subedge = Spine.getSubValues(); TopoDS_Shape path; const Part::TopoShape& shape = static_cast<Part::Feature*>(spine)->Shape.getValue(); if (!shape._Shape.IsNull()) { try { if (!subedge.empty()) { BRepBuilderAPI_MakeWire mkWire; for (std::vector<std::string>::const_iterator it = subedge.begin(); it != subedge.end(); ++it) { TopoDS_Shape subshape = shape.getSubShape(it->c_str()); mkWire.Add(TopoDS::Edge(subshape)); } path = mkWire.Wire(); } else if (shape._Shape.ShapeType() == TopAbs_EDGE) { path = shape._Shape; } else if (shape._Shape.ShapeType() == TopAbs_WIRE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape)); path = mkWire.Wire(); } else if (shape._Shape.ShapeType() == TopAbs_COMPOUND) { TopoDS_Iterator it(shape._Shape); for (; it.More(); it.Next()) { if (it.Value().IsNull()) return new App::DocumentObjectExecReturn("In valid element in spine."); if ((it.Value().ShapeType() != TopAbs_EDGE) && (it.Value().ShapeType() != TopAbs_WIRE)) { return new App::DocumentObjectExecReturn("Element in spine is neither an edge nor a wire."); } } Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape(); Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape(); for (TopExp_Explorer xp(shape._Shape, TopAbs_EDGE); xp.More(); xp.Next()) hEdges->Append(xp.Current()); ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_True, hWires); int len = hWires->Length(); if (len != 1) return new App::DocumentObjectExecReturn("Spine is not connected."); path = hWires->Value(1); } else { return new App::DocumentObjectExecReturn("Spine is neither an edge nor a wire."); } } catch (Standard_Failure) { return new App::DocumentObjectExecReturn("Invalid spine."); } } try { TopTools_ListOfShape profiles; const std::vector<App::DocumentObject*>& shapes = Sections.getValues(); std::vector<App::DocumentObject*>::const_iterator it; for (it = shapes.begin(); it != shapes.end(); ++it) { if (!(*it)->isDerivedFrom(Part::Feature::getClassTypeId())) return new App::DocumentObjectExecReturn("Linked object is not a shape."); TopoDS_Shape shape = static_cast<Part::Feature*>(*it)->Shape.getValue(); if (shape.IsNull()) return new App::DocumentObjectExecReturn("Linked shape is invalid."); // Extract first element of a compound if (shape.ShapeType() == TopAbs_COMPOUND) { TopoDS_Iterator it(shape); for (; it.More(); it.Next()) { if (!it.Value().IsNull()) { shape = it.Value(); break; } } } // There is a weird behaviour of BRepOffsetAPI_MakePipeShell when trying to add the wire as is. // If we re-create the wire then everything works fine. // http://forum.freecadweb.org/viewtopic.php?f=10&t=2673&sid=fbcd2ff4589f0b2f79ed899b0b990648#p20268 if (shape.ShapeType() == TopAbs_FACE) { TopoDS_Wire faceouterWire = ShapeAnalysis::OuterWire(TopoDS::Face(shape)); profiles.Append(faceouterWire); } else if (shape.ShapeType() == TopAbs_WIRE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape)); profiles.Append(mkWire.Wire()); } else if (shape.ShapeType() == TopAbs_EDGE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(shape)); profiles.Append(mkWire.Wire()); } else if (shape.ShapeType() == TopAbs_VERTEX) { profiles.Append(shape); } else { return new App::DocumentObjectExecReturn("Linked shape is not a vertex, edge, wire nor face."); } } Standard_Boolean isSolid = Solid.getValue() ? Standard_True : Standard_False; Standard_Boolean isFrenet = Frenet.getValue() ? Standard_True : Standard_False; BRepBuilderAPI_TransitionMode transMode; switch (Transition.getValue()) { case 1: transMode = BRepBuilderAPI_RightCorner; break; case 2: transMode = BRepBuilderAPI_RoundCorner; break; default: transMode = BRepBuilderAPI_Transformed; break; } if (path.ShapeType() == TopAbs_EDGE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(path)); path = mkWire.Wire(); } BRepOffsetAPI_MakePipeShell mkPipeShell(TopoDS::Wire(path)); mkPipeShell.SetMode(isFrenet); mkPipeShell.SetTransitionMode(transMode); TopTools_ListIteratorOfListOfShape iter; for (iter.Initialize(profiles); iter.More(); iter.Next()) { mkPipeShell.Add(TopoDS_Shape(iter.Value())); } if (!mkPipeShell.IsReady()) Standard_Failure::Raise("shape is not ready to build"); mkPipeShell.Build(); if (isSolid) mkPipeShell.MakeSolid(); this->Shape.setValue(mkPipeShell.Shape()); return App::DocumentObject::StdReturn; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); return new App::DocumentObjectExecReturn(e->GetMessageString()); } catch (...) { return new App::DocumentObjectExecReturn("A fatal error occurred when making the sweep"); } }
// constructor method int TopoShapeWirePy::PyInit(PyObject* args, PyObject* /*kwd*/) { PyObject *pcObj; if (PyArg_ParseTuple(args, "O!", &(Part::TopoShapePy::Type), &pcObj)) { BRepBuilderAPI_MakeWire mkWire; const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(pcObj)->getTopoShapePtr()->_Shape; if (sh.IsNull()) { PyErr_SetString(PyExc_TypeError, "given shape is invalid"); return -1; } if (sh.ShapeType() == TopAbs_EDGE) mkWire.Add(TopoDS::Edge(sh)); else if (sh.ShapeType() == TopAbs_WIRE) mkWire.Add(TopoDS::Wire(sh)); else { PyErr_SetString(PyExc_TypeError, "shape is neither edge nor wire"); return -1; } try { getTopoShapePtr()->_Shape = mkWire.Wire(); return 0; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PyExc_Exception, e->GetMessageString()); return -1; } } PyErr_Clear(); if (PyArg_ParseTuple(args, "O!", &(PyList_Type), &pcObj)) { BRepBuilderAPI_MakeWire mkWire; Py::List list(pcObj); for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { PyObject* item = (*it).ptr(); if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) { const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(item)->getTopoShapePtr()->_Shape; if (sh.IsNull()) { PyErr_SetString(PyExc_TypeError, "given shape is invalid"); return -1; } if (sh.ShapeType() == TopAbs_EDGE) mkWire.Add(TopoDS::Edge(sh)); else if (sh.ShapeType() == TopAbs_WIRE) mkWire.Add(TopoDS::Wire(sh)); else { PyErr_SetString(PyExc_TypeError, "shape is neither edge nor wire"); return -1; } } else { PyErr_SetString(PyExc_TypeError, "item is not a shape"); return -1; } } try { getTopoShapePtr()->_Shape = mkWire.Wire(); return 0; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PyExc_Exception, e->GetMessageString()); return -1; } } PyErr_SetString(PyExc_Exception, "edge or wire or list of edges and wires expected"); return -1; }
//======================================================================= // profile // command to build a profile //======================================================================= Sketcher_Profile::Sketcher_Profile(const char* aCmd) { enum {line, circle, point, none} move; Standard_Integer i = 1; Standard_Real x0, y0, x, y, dx, dy; x0 = y0 = x = y = dy = 0; dx = 1; Standard_Boolean first, stayfirst, face, close; first = Standard_True; stayfirst = face = close = Standard_False; Standard_Integer reversed = 0; Standard_Integer control_Tolerance = 0; TopoDS_Shape S; TopoDS_Vertex MP; BRepBuilderAPI_MakeWire MW; gp_Ax3 DummyHP(gp::XOY()); gp_Pln P(DummyHP); TopLoc_Location TheLocation; Handle(Geom_Surface) Surface; myOK = Standard_False; myError = 0; //TCollection_AsciiString aCommand(CORBA::string_dup(aCmd)); TCollection_AsciiString aCommand ((char*)aCmd); TCollection_AsciiString aToken = aCommand.Token(":", 1); int n = 0; // porting to WNT TColStd_Array1OfAsciiString aTab (0, aCommand.Length() - 1); if ( aCommand.Length() ) { while(aToken.Length() != 0) { if(aCommand.Token(":", n + 1).Length() > 0) aTab(n) = aCommand.Token(":", n + 1); aToken = aCommand.Token(":", ++n); } n = n - 1; } if ( aTab.Length() && aTab(0).Length() ) while(i < n) { Standard_Real length = 0, radius = 0, angle = 0; move = point; int n1 = 0; TColStd_Array1OfAsciiString a (0, aTab(0).Length()); aToken = aTab(i).Token(" ", 1); while (aToken.Length() != 0) { if (aTab(i).Token(" ", n1 + 1).Length() > 0) a(n1) = aTab(i).Token(" ", n1 + 1); aToken = aTab(i).Token(" ", ++n1); } n1 = n1 - 1; switch(a(0).Value(1)) { case 'F': { if (n1 != 3) goto badargs; if (!first) { MESSAGE("profile : The F instruction must precede all moves"); return; } x0 = x = a(1).RealValue(); y0 = y = a(2).RealValue(); stayfirst = Standard_True; break; } case 'O': { if (n1 != 4) goto badargs; P.SetLocation(gp_Pnt(a(1).RealValue(), a(2).RealValue(), a(3).RealValue())); stayfirst = Standard_True; break; } case 'P': { if (n1 != 7) goto badargs; gp_Vec vn(a(1).RealValue(), a(2).RealValue(), a(3).RealValue()); gp_Vec vx(a(4).RealValue(), a(5).RealValue(), a(6).RealValue()); if (vn.Magnitude() <= Precision::Confusion() || vx.Magnitude() <= Precision::Confusion()) { MESSAGE("profile : null direction"); return; } gp_Ax2 ax(P.Location(), vn, vx); P.SetPosition(ax); stayfirst = Standard_True; break; } case 'X': { if (n1 != 2) goto badargs; length = a(1).RealValue(); if (a(0) == "XX") length -= x; dx = 1; dy = 0; move = line; break; } case 'Y': { if (n1 != 2) goto badargs; length = a(1).RealValue(); if (a(0) == "YY") length -= y; dx = 0; dy = 1; move = line; break; } case 'L': { if (n1 != 2) goto badargs; length = a(1).RealValue(); if (Abs(length) > Precision::Confusion()) move = line; else move = none; break; } case 'T': { if (n1 != 3) goto badargs; Standard_Real vx = a(1).RealValue(); Standard_Real vy = a(2).RealValue(); if (a(0) == "TT") { vx -= x; vy -= y; } length = Sqrt(vx * vx + vy * vy); if (length > Precision::Confusion()) { move = line; dx = vx / length; dy = vy / length; } else move = none; break; } case 'R': { if (n1 != 2) goto badargs; angle = a(1).RealValue() * PI180; if (a(0) == "RR") { dx = Cos(angle); dy = Sin(angle); } else { Standard_Real c = Cos(angle); Standard_Real s = Sin(angle); Standard_Real t = c * dx - s * dy; dy = s * dx + c * dy; dx = t; } break; } case 'D': { if (n1 != 3) goto badargs; Standard_Real vx = a(1).RealValue(); Standard_Real vy = a(2).RealValue(); length = Sqrt(vx * vx + vy * vy); if (length > Precision::Confusion()) { dx = vx / length; dy = vy / length; } else move = none; break; } case 'C': { if (n1 != 3) goto badargs; radius = a(1).RealValue(); if (Abs(radius) > Precision::Confusion()) { angle = a(2).RealValue() * PI180; move = circle; } else move = none; break; } case 'A': // TAngential arc by end point { if (n1 != 3) goto badargs; Standard_Real vx = a(1).RealValue(); Standard_Real vy = a(2).RealValue(); if (a(0) == "AA") { vx -= x; vy -= y; } Standard_Real det = dx * vy - dy * vx; if ( Abs(det) > Precision::Confusion()) { Standard_Real c = (dx * vx + dy * vy) / Sqrt((dx * dx + dy * dy) * (vx * vx + vy * vy)); // Cosine of alpha = arc of angle / 2 , alpha in [0,Pi] radius = (vx * vx + vy * vy)* Sqrt(dx * dx + dy * dy) // radius = distance between start and end point / 2 * sin(alpha) / (2.0 * det); // radius is > 0 or < 0 if (Abs(radius) > Precision::Confusion()) { angle = 2.0 * acos(c); // angle in [0,2Pi] move = circle; } else move = none; break; } else move = none; break; } case 'U': // Arc by end point and radiUs { if (n1 != 5) goto badargs; Standard_Real vx = a(1).RealValue(); Standard_Real vy = a(2).RealValue(); radius = a(3).RealValue(); reversed = a(4).IntegerValue(); if (a(0) == "UU") { // Absolute vx -= x; vy -= y; } Standard_Real length = Sqrt(vx * vx + vy * vy); if ( (4.0 - (vx * vx + vy * vy) / (radius * radius) >= 0.0 ) && (length > Precision::Confusion()) ) { Standard_Real c = 0.5 * Sqrt(4.0 - (vx * vx + vy * vy) / (radius * radius)); // Cosine of alpha = arc angle / 2 , alpha in [0,Pi/2] angle = 2.0 * acos(c); // angle in [0,Pi] if ( reversed == 2 ) angle = angle - 2 * PI; dx = 0.5 * ( vy * 1.0/radius + vx * Sqrt(4.0 / (vx * vx + vy * vy) - 1.0 / (radius * radius))); dy = - 0.5 * ( vx * 1.0/radius - vy * Sqrt(4.0 / (vx * vx + vy * vy) - 1.0 / (radius * radius))); move = circle; } else{ move = none; } break; } case 'E': // Arc by end point and cEnter { if (n1 != 7) goto badargs; Standard_Real vx = a(1).RealValue(); Standard_Real vy = a(2).RealValue(); Standard_Real vxc = a(3).RealValue(); Standard_Real vyc = a(4).RealValue(); reversed = a(5).IntegerValue(); control_Tolerance = a(6).IntegerValue(); if (a(0) == "EE") { // Absolute vx -= x; vy -= y; vxc -= x; vyc -= y; } radius = Sqrt( vxc * vxc + vyc * vyc ); Standard_Real det = vx * vyc - vy * vxc; Standard_Real length = Sqrt(vx * vx + vy * vy); Standard_Real length2 = Sqrt((vx-vxc) * (vx-vxc) + (vy-vyc) * (vy-vyc)); Standard_Real length3 = Sqrt(vxc * vxc + vyc * vyc); Standard_Real error = Abs(length2 - radius); myError = error; if ( error > Precision::Confusion() ){ MESSAGE("Warning : The specified end point is not on the Arc, distance = "<<error); } if ( error > Precision::Confusion() && control_Tolerance == 1) // Don't create the arc if the end point move = none; // is too far from it else if ( (length > Precision::Confusion()) && (length2 > Precision::Confusion()) && (length3 > Precision::Confusion()) ) { Standard_Real c = ( radius * radius - (vx * vxc + vy * vyc) ) / ( radius * Sqrt((vx-vxc) * (vx-vxc) + (vy-vyc) * (vy-vyc)) ) ; // Cosine of arc angle angle = acos(c); // angle in [0,Pi] if ( reversed == 2 ) angle = angle - 2 * PI; if (det < 0) angle = -angle; dx = vyc / radius; dy = -vxc / radius; move = circle; } else { move = none; } break; } case 'I': { if (n1 != 2) goto badargs; length = a(1).RealValue(); if (a(0) == "IX") { if (Abs(dx) < Precision::Confusion()) { MESSAGE("profile : cannot intersect, arg "<<i-1); return; } length = (length - x) / dx; } else if (a(0) == "IY") { if (Abs(dy) < Precision::Confusion()) { MESSAGE("profile : cannot intersect, arg "<<i-1); return; } length = (length - y) / dy; } if (Abs(length) > Precision::Confusion()) move = line; else move = none; break; } case 'W': { if (a(0) == "WW") close = Standard_True; else if(a(0) == "WF") { close = Standard_True; face = Standard_True; } i = n - 1; break; } default: { MESSAGE("profile : unknown code " << a(i)); return; } } again : switch (move) { case line : { if (length < 0) { length = -length; dx = -dx; dy = -dy; } Handle(Geom2d_Line) l = new Geom2d_Line(gp_Pnt2d(x,y),gp_Dir2d(dx,dy)); BRepBuilderAPI_MakeEdge ME (GeomAPI::To3d(l,P),0,length); if (!ME.IsDone()) return; MW.Add(ME); x += length*dx; y += length*dy; break; } case circle : { Standard_Boolean sense = Standard_True; if (radius < 0) { radius = -radius; sense = !sense; dx = -dx; dy = -dy; } gp_Ax2d ax(gp_Pnt2d(x-radius*dy,y+radius*dx),gp_Dir2d(dy,-dx)); if (angle < 0) { angle = -angle; sense = !sense; } Handle(Geom2d_Circle) c = new Geom2d_Circle(ax,radius,sense); BRepBuilderAPI_MakeEdge ME (GeomAPI::To3d(c,P),0,angle); if (!ME.IsDone()) return; MW.Add(ME); gp_Pnt2d p; gp_Vec2d v; c->D1(angle,p,v); x = p.X(); y = p.Y(); dx = v.X() / radius; dy = v.Y() / radius; break; } case point: { MP = BRepBuilderAPI_MakeVertex(gp_Pnt(x, y, 0.0)); break; } case none: { i = n - 1; break; } } // update first first = stayfirst; stayfirst = Standard_False; if(!(dx == 0 && dy == 0)) myLastDir.SetCoord(dx, dy, 0.0); else return; myLastPoint.SetX(x); myLastPoint.SetY(y); // next segment.... i++; if ((i == n) && close) { // the closing segment dx = x0 - x; dy = y0 - y; length = Sqrt(dx * dx + dy * dy); move = line; if (length > Precision::Confusion()) { dx = dx / length; dy = dy / length; goto again; } } } // get the result, face or wire if (move == none) { return; } else if (move == point) { S = MP; } else if (face) { if (!MW.IsDone()) { return; } BRepBuilderAPI_MakeFace MF (P, MW.Wire()); if (!MF.IsDone()) { return; } S = MF; } else { if (!MW.IsDone()) { return; } S = MW; } if(!TheLocation.IsIdentity()) S.Move(TheLocation); myShape = S; myOK = true; return; badargs : MESSAGE("profile : bad number of arguments"); return; }
//======================================================================= //function : Execute //purpose : //======================================================================= Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const { if (Label().IsNull()) return 0; Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); GEOMImpl_IFillet1d aCI (aFunction); Handle(GEOM_Function) aRefShape = aCI.GetShape(); TopoDS_Shape aShape = aRefShape->GetValue(); if (aShape.IsNull()) return 0; if (aShape.ShapeType() != TopAbs_WIRE) Standard_ConstructionError::Raise("Wrong arguments: polyline as wire must be given"); TopoDS_Wire aWire = TopoDS::Wire(aShape); double rad = aCI.GetR(); if ( rad < Precision::Confusion()) return 0; // collect vertices for make fillet TopTools_ListOfShape aVertexList; TopTools_MapOfShape mapShape; int aLen = aCI.GetLength(); if ( aLen > 0 ) { for (int ind = 1; ind <= aLen; ind++) { TopoDS_Shape aShapeVertex; if (GEOMImpl_ILocalOperations::GetSubShape (aWire, aCI.GetVertex(ind), aShapeVertex)) if (mapShape.Add(aShapeVertex)) aVertexList.Append( aShapeVertex ); } } else { // get all vertices from wire TopExp_Explorer anExp( aWire, TopAbs_VERTEX ); for ( ; anExp.More(); anExp.Next() ) { if (mapShape.Add(anExp.Current())) aVertexList.Append( anExp.Current() ); } } if (aVertexList.IsEmpty()) Standard_ConstructionError::Raise("Invalid input no vertices to make fillet"); //INFO: this algorithm implemented in assumption that user can select both // vertices of some edges to make fillet. In this case we should remember // already modified initial edges to take care in next fillet step TopTools_DataMapOfShapeShape anEdgeToEdgeMap; //iterates on vertices, and make fillet on each couple of edges //collect result fillet edges in list TopTools_ListOfShape aListOfNewEdge; // remember relation between initial and modified map TopTools_IndexedDataMapOfShapeListOfShape aMapVToEdges; TopExp::MapShapesAndAncestors( aWire, TopAbs_VERTEX, TopAbs_EDGE, aMapVToEdges ); TopTools_ListIteratorOfListOfShape anIt( aVertexList ); for ( ; anIt.More(); anIt.Next() ) { TopoDS_Vertex aV = TopoDS::Vertex( anIt.Value() ); if ( aV.IsNull() || !aMapVToEdges.Contains( aV ) ) continue; const TopTools_ListOfShape& aVertexEdges = aMapVToEdges.FindFromKey( aV ); if ( aVertexEdges.Extent() != 2 ) continue; // no input data to make fillet TopoDS_Edge anEdge1 = TopoDS::Edge( aVertexEdges.First() ); TopoDS_Edge anEdge2 = TopoDS::Edge( aVertexEdges.Last() ); // check if initial edges already modified in previous fillet operation if ( anEdgeToEdgeMap.IsBound( anEdge1 ) ) anEdge1 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge1 )); if ( anEdgeToEdgeMap.IsBound( anEdge2 ) ) anEdge2 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge2 )); if ( anEdge1.IsNull() || anEdge2.IsNull() || anEdge1.IsSame( anEdge2 ) ) continue; //no input data to make fillet // create plane on 2 edges gp_Pln aPlane; if ( !takePlane(anEdge1, anEdge2, aV, aPlane) ) continue; // seems edges does not belong to same plane or parallel (fillet can not be build) GEOMImpl_Fillet1d aFilletAlgo(anEdge1, anEdge2, aPlane); if ( !aFilletAlgo.Perform(rad) ) continue; // can not create fillet with given radius // take fillet result in given vertex TopoDS_Edge aModifE1, aModifE2; TopoDS_Edge aNewE = aFilletAlgo.Result(BRep_Tool::Pnt(aV), aModifE1, aModifE2); if (aNewE.IsNull()) continue; // no result found // add new created edges and take modified edges aListOfNewEdge.Append( aNewE ); // check if face edges modified, // if yes, than map to original edges (from vertex-edges list), because edges can be modified before if (aModifE1.IsNull() || !anEdge1.IsSame( aModifE1 )) addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.First()), aModifE1 ); if (aModifE2.IsNull() || !anEdge2.IsSame( aModifE2 )) addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.Last()), aModifE2 ); } if ( anEdgeToEdgeMap.IsEmpty() && aListOfNewEdge.IsEmpty() ) { StdFail_NotDone::Raise("1D Fillet can't be computed on the given shape with the given radius"); return 0; } // create new wire instead of original for ( TopExp_Explorer anExp( aWire, TopAbs_EDGE ); anExp.More(); anExp.Next() ) { TopoDS_Shape anEdge = anExp.Current(); if ( !anEdgeToEdgeMap.IsBound( anEdge ) ) aListOfNewEdge.Append( anEdge ); else if (!anEdgeToEdgeMap.Find( anEdge ).IsNull()) aListOfNewEdge.Append( anEdgeToEdgeMap.Find( anEdge ) ); } GEOMImpl_IShapesOperations::SortShapes( aListOfNewEdge ); BRepBuilderAPI_MakeWire aWireTool; aWireTool.Add( aListOfNewEdge ); aWireTool.Build(); if (!aWireTool.IsDone()) return 0; aWire = aWireTool.Wire(); aFunction->SetValue(aWire); log.SetTouched(Label()); return 1; }
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire& wire) { if ( getValue(GV_PLANEANGLE_UNIT)<0 ) { Logger::Message(Logger::LOG_WARNING,"Creating a composite curve without unit information:",l->entity); // Temporarily pretend we do have unit information setValue(GV_PLANEANGLE_UNIT,1.0); bool succes_radians = false; bool succes_degrees = false; bool use_radians = false; bool use_degrees = false; // First try radians TopoDS_Wire wire_radians, wire_degrees; try { succes_radians = IfcGeom::Kernel::convert(l,wire_radians); } catch (...) {} // Now try degrees setValue(GV_PLANEANGLE_UNIT,0.0174532925199433); try { succes_degrees = IfcGeom::Kernel::convert(l,wire_degrees); } catch (...) {} // Restore to unknown unit state setValue(GV_PLANEANGLE_UNIT,-1.0); if ( succes_degrees && ! succes_radians ) { use_degrees = true; } else if ( succes_radians && ! succes_degrees ) { use_radians = true; } else if ( succes_radians && succes_degrees ) { if ( wire_degrees.Closed() && ! wire_radians.Closed() ) { use_degrees = true; } else if ( wire_radians.Closed() && ! wire_degrees.Closed() ) { use_radians = true; } else { // No heuristic left to prefer the one over the other, // apparently both variants are equally succesful. // The curve might be composed of only straight segments. // Let's go with the wire created using radians as that // at least is a SI unit. use_radians = true; } } if ( use_radians ) { Logger::Message(Logger::LOG_NOTICE,"Used radians to create composite curve"); wire = wire_radians; } else if ( use_degrees ) { Logger::Message(Logger::LOG_NOTICE,"Used degrees to create composite curve"); wire = wire_degrees; } return use_radians || use_degrees; } IfcSchema::IfcCompositeCurveSegment::list::ptr segments = l->Segments(); BRepBuilderAPI_MakeWire w; //TopoDS_Vertex last_vertex; for( IfcSchema::IfcCompositeCurveSegment::list::it it = segments->begin(); it != segments->end(); ++ it ) { IfcSchema::IfcCurve* curve = (*it)->ParentCurve(); TopoDS_Wire wire2; if ( !convert_wire(curve,wire2) ) { Logger::Message(Logger::LOG_ERROR,"Failed to convert curve:",curve->entity); continue; } if ( ! (*it)->SameSense() ) wire2.Reverse(); ShapeFix_ShapeTolerance FTol; FTol.SetTolerance(wire2, getValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_WIRE); /*if ( it != segments->begin() ) { TopExp_Explorer exp (wire2,TopAbs_VERTEX); const TopoDS_Vertex& first_vertex = TopoDS::Vertex(exp.Current()); gp_Pnt first = BRep_Tool::Pnt(first_vertex); gp_Pnt last = BRep_Tool::Pnt(last_vertex); Standard_Real distance = first.Distance(last); if ( distance > ALMOST_ZERO ) { w.Add( BRepBuilderAPI_MakeEdge( last_vertex, first_vertex ) ); } }*/ w.Add(wire2); //last_vertex = w.Vertex(); if ( w.Error() != BRepBuilderAPI_WireDone ) { Logger::Message(Logger::LOG_ERROR,"Failed to join curve segments:",l->entity); return false; } } wire = w.Wire(); return true; }
bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire& wire) { IfcSchema::IfcCurve* basis_curve = l->BasisCurve(); bool isConic = basis_curve->is(IfcSchema::Type::IfcConic); double parameterFactor = isConic ? getValue(GV_PLANEANGLE_UNIT) : getValue(GV_LENGTH_UNIT); Handle(Geom_Curve) curve; if ( !convert_curve(basis_curve,curve) ) return false; bool trim_cartesian = l->MasterRepresentation() == IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_CARTESIAN; IfcEntityList::ptr trims1 = l->Trim1(); IfcEntityList::ptr trims2 = l->Trim2(); bool trimmed1 = false; bool trimmed2 = false; unsigned sense_agreement = l->SenseAgreement() ? 0 : 1; double flts[2]; gp_Pnt pnts[2]; bool has_flts[2] = {false,false}; bool has_pnts[2] = {false,false}; BRepBuilderAPI_MakeWire w; for ( IfcEntityList::it it = trims1->begin(); it != trims1->end(); it ++ ) { IfcUtil::IfcBaseClass* i = *it; if ( i->is(IfcSchema::Type::IfcCartesianPoint) ) { IfcGeom::Kernel::convert((IfcSchema::IfcCartesianPoint*)i, pnts[sense_agreement] ); has_pnts[sense_agreement] = true; } else if ( i->is(IfcSchema::Type::IfcParameterValue) ) { const double value = *((IfcSchema::IfcParameterValue*)i); flts[sense_agreement] = value * parameterFactor; has_flts[sense_agreement] = true; } } for ( IfcEntityList::it it = trims2->begin(); it != trims2->end(); it ++ ) { IfcUtil::IfcBaseClass* i = *it; if ( i->is(IfcSchema::Type::IfcCartesianPoint) ) { IfcGeom::Kernel::convert((IfcSchema::IfcCartesianPoint*)i, pnts[1-sense_agreement] ); has_pnts[1-sense_agreement] = true; } else if ( i->is(IfcSchema::Type::IfcParameterValue) ) { const double value = *((IfcSchema::IfcParameterValue*)i); flts[1-sense_agreement] = value * parameterFactor; has_flts[1-sense_agreement] = true; } } trim_cartesian &= has_pnts[0] && has_pnts[1]; bool trim_cartesian_failed = !trim_cartesian; if ( trim_cartesian ) { if ( pnts[0].Distance(pnts[1]) < getValue(GV_WIRE_CREATION_TOLERANCE) ) { Logger::Message(Logger::LOG_WARNING,"Skipping segment with length below tolerance level:",l->entity); return false; } ShapeFix_ShapeTolerance FTol; TopoDS_Vertex v1 = BRepBuilderAPI_MakeVertex(pnts[0]); TopoDS_Vertex v2 = BRepBuilderAPI_MakeVertex(pnts[1]); FTol.SetTolerance(v1, getValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_VERTEX); FTol.SetTolerance(v2, getValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_VERTEX); BRepBuilderAPI_MakeEdge e (curve,v1,v2); if ( ! e.IsDone() ) { BRepBuilderAPI_EdgeError err = e.Error(); if ( err == BRepBuilderAPI_PointProjectionFailed ) { Logger::Message(Logger::LOG_WARNING,"Point projection failed for:",l->entity); trim_cartesian_failed = true; } } else { w.Add(e.Edge()); } } if ( (!trim_cartesian || trim_cartesian_failed) && (has_flts[0] && has_flts[1]) ) { // The Geom_Line is constructed from a gp_Pnt and gp_Dir, whereas the IfcLine // is defined by an IfcCartesianPoint and an IfcVector with Magnitude. Because // the vector is normalised when passed to Geom_Line constructor the magnitude // needs to be factored in with the IfcParameterValue here. if ( basis_curve->is(IfcSchema::Type::IfcLine) ) { IfcSchema::IfcLine* line = static_cast<IfcSchema::IfcLine*>(basis_curve); const double magnitude = line->Dir()->Magnitude(); flts[0] *= magnitude; flts[1] *= magnitude; } if ( basis_curve->is(IfcSchema::Type::IfcEllipse) ) { IfcSchema::IfcEllipse* ellipse = static_cast<IfcSchema::IfcEllipse*>(basis_curve); double x = ellipse->SemiAxis1() * getValue(GV_LENGTH_UNIT); double y = ellipse->SemiAxis2() * getValue(GV_LENGTH_UNIT); const bool rotated = y > x; if (rotated) { flts[0] -= M_PI / 2.; flts[1] -= M_PI / 2.; } } if ( isConic && ALMOST_THE_SAME(fmod(flts[1]-flts[0],(double)(M_PI*2.0)),0.0f) ) { w.Add(BRepBuilderAPI_MakeEdge(curve)); } else { BRepBuilderAPI_MakeEdge e (curve,flts[0],flts[1]); w.Add(e.Edge()); } } else if ( trim_cartesian_failed && (has_pnts[0] && has_pnts[1]) ) { w.Add(BRepBuilderAPI_MakeEdge(pnts[0],pnts[1])); } if ( w.IsDone() ) { wire = w.Wire(); return true; } else { return false; } }