bool FaceMakerCheese::Wire_Compare::operator() (const TopoDS_Wire& w1, const TopoDS_Wire& w2) { Bnd_Box box1, box2; if (!w1.IsNull()) { BRepBndLib::Add(w1, box1); box1.SetGap(0.0); } if (!w2.IsNull()) { BRepBndLib::Add(w2, box2); box2.SetGap(0.0); } return box1.SquareExtent() < box2.SquareExtent(); }
//! return true if w1 bbox is bigger than w2 bbox //NOTE: this won't necessarily sort the OuterWire correctly (ex smaller wire, same bbox) /*static*/bool EdgeWalker::wireCompare(const TopoDS_Wire& w1, const TopoDS_Wire& w2) { Bnd_Box box1, box2; if (!w1.IsNull()) { BRepBndLib::Add(w1, box1); box1.SetGap(0.0); } if (!w2.IsNull()) { BRepBndLib::Add(w2, box2); box2.SetGap(0.0); } return box1.SquareExtent() > box2.SquareExtent(); }
void Extrusion::makeDraft(ExtrusionParameters params, const TopoDS_Shape& shape, std::list<TopoDS_Shape>& drafts) { double distanceFwd = tan(params.taperAngleFwd)*params.lengthFwd; double distanceRev = tan(params.taperAngleRev)*params.lengthRev; gp_Vec vecFwd = gp_Vec(params.dir)*params.lengthFwd; gp_Vec vecRev = gp_Vec(params.dir.Reversed())*params.lengthRev; bool bFwd = fabs(params.lengthFwd) > Precision::Confusion(); bool bRev = fabs(params.lengthRev) > Precision::Confusion(); bool bMid = !bFwd || !bRev || params.lengthFwd*params.lengthRev > 0.0; //include the source shape as loft section? TopoDS_Wire sourceWire; if (shape.IsNull()) Standard_Failure::Raise("Not a valid shape"); if (shape.ShapeType() == TopAbs_WIRE) { ShapeFix_Wire aFix; aFix.Load(TopoDS::Wire(shape)); aFix.FixReorder(); aFix.FixConnected(); aFix.FixClosed(); sourceWire = aFix.Wire(); } else if (shape.ShapeType() == TopAbs_FACE) { TopoDS_Wire outerWire = ShapeAnalysis::OuterWire(TopoDS::Face(shape)); sourceWire = outerWire; } else if (shape.ShapeType() == TopAbs_COMPOUND) { TopoDS_Iterator it(shape); for (; it.More(); it.Next()) { makeDraft(params, it.Value(), drafts); } } else { Standard_Failure::Raise("Only a wire or a face is supported"); } if (!sourceWire.IsNull()) { std::list<TopoDS_Wire> list_of_sections; //first. add wire for reversed part of extrusion if (bRev){ gp_Vec translation = vecRev; double offset = distanceRev; BRepOffsetAPI_MakeOffset mkOffset; #if OCC_VERSION_HEX >= 0x060800 mkOffset.Init(GeomAbs_Arc); #endif #if OCC_VERSION_HEX >= 0x070000 mkOffset.Init(GeomAbs_Intersection); #endif gp_Trsf mat; mat.SetTranslation(translation); TopLoc_Location loc(mat); TopoDS_Wire movedSourceWire = TopoDS::Wire(sourceWire.Moved(loc)); TopoDS_Shape offsetShape; if (fabs(offset)>Precision::Confusion()){ mkOffset.AddWire(movedSourceWire); mkOffset.Perform(offset); offsetShape = mkOffset.Shape(); } else { //stupid OCC doesn't understand, what to do when offset value is zero =/ offsetShape = movedSourceWire; } if (offsetShape.IsNull()) Standard_Failure::Raise("Tapered shape is empty"); TopAbs_ShapeEnum type = offsetShape.ShapeType(); if (type == TopAbs_WIRE) { list_of_sections.push_back(TopoDS::Wire(offsetShape)); } else if (type == TopAbs_EDGE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(offsetShape)); list_of_sections.push_back(mkWire.Wire()); } else { Standard_Failure::Raise("Tapered shape type is not supported"); } } //next. Add source wire as middle section. Order is important. if (bMid){ list_of_sections.push_back(sourceWire); } //finally. Forward extrusion offset wire. if (bFwd){ gp_Vec translation = vecFwd; double offset = distanceFwd; BRepOffsetAPI_MakeOffset mkOffset; #if OCC_VERSION_HEX >= 0x060800 mkOffset.Init(GeomAbs_Arc); #endif #if OCC_VERSION_HEX >= 0x070000 mkOffset.Init(GeomAbs_Intersection); #endif gp_Trsf mat; mat.SetTranslation(translation); TopLoc_Location loc(mat); TopoDS_Wire movedSourceWire = TopoDS::Wire(sourceWire.Moved(loc)); TopoDS_Shape offsetShape; if (fabs(offset)>Precision::Confusion()){ mkOffset.AddWire(movedSourceWire); mkOffset.Perform(offset); offsetShape = mkOffset.Shape(); } else { //stupid OCC doesn't understand, what to do when offset value is zero =/ offsetShape = movedSourceWire; } if (offsetShape.IsNull()) Standard_Failure::Raise("Tapered shape is empty"); TopAbs_ShapeEnum type = offsetShape.ShapeType(); if (type == TopAbs_WIRE) { list_of_sections.push_back(TopoDS::Wire(offsetShape)); } else if (type == TopAbs_EDGE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(offsetShape)); list_of_sections.push_back(mkWire.Wire()); } else { Standard_Failure::Raise("Tapered shape type is not supported"); } } //make loft BRepOffsetAPI_ThruSections mkGenerator(params.solid ? Standard_True : Standard_False, /*ruled=*/Standard_True); for (std::list<TopoDS_Wire>::const_iterator it = list_of_sections.begin(); it != list_of_sections.end(); ++it) { const TopoDS_Wire &wire = *it; mkGenerator.AddWire(wire); } try { #if defined(__GNUC__) && defined (FC_OS_LINUX) Base::SignalException se; #endif mkGenerator.Build(); drafts.push_back(mkGenerator.Shape()); } catch (Standard_Failure &){ throw; } catch (...) { throw Base::Exception("Unknown exception from BRepOffsetAPI_ThruSections"); } } }