Standard_Boolean Reject(const Bnd_Box& bb) const { const bool result = bb.IsOpenXmin() == Standard_True || bb.IsOpenXmax() == Standard_True || bb.IsOpenYmin() == Standard_True || bb.IsOpenYmax() == Standard_True || bb.IsOpenZmin() == Standard_True || bb.IsOpenZmax() == Standard_True || bb.IsWhole() == Standard_True || bb.IsVoid() == Standard_True; return result ? Standard_True : Standard_False; }
Base::BoundBox3d GeometryObject::calcBoundingBox() const { Bnd_Box testBox; testBox.SetGap(0.0); for (std::vector<BaseGeom *>::const_iterator it( edgeGeom.begin() ); it != edgeGeom.end(); ++it) { BRepBndLib::Add((*it)->occEdge, testBox); } if (testBox.IsVoid()) { Base::Console().Log("INFO - GO::calcBoundingBox - testBox is void\n"); } double xMin,xMax,yMin,yMax,zMin,zMax; testBox.Get(xMin,yMin,zMin,xMax,yMax,zMax); Base::BoundBox3d bbox(xMin,yMin,zMin,xMax,yMax,zMax); return bbox; }
//this routine is the big time consumer. gets called many times (and is slow?)) //note param gets modified here bool DrawProjectSplit::isOnEdge(TopoDS_Edge e, TopoDS_Vertex v, double& param, bool allowEnds) { bool result = false; bool outOfBox = false; param = -2; //eliminate obvious cases Bnd_Box sBox; BRepBndLib::Add(e, sBox); sBox.SetGap(0.1); if (sBox.IsVoid()) { Base::Console().Message("DPS::isOnEdge - Bnd_Box is void\n"); } else { gp_Pnt pt = BRep_Tool::Pnt(v); if (sBox.IsOut(pt)) { outOfBox = true; } } if (!outOfBox) { double dist = DrawUtil::simpleMinDist(v,e); if (dist < 0.0) { Base::Console().Error("DPS::isOnEdge - simpleMinDist failed: %.3f\n",dist); result = false; } else if (dist < Precision::Confusion()) { const gp_Pnt pt = BRep_Tool::Pnt(v); //have to duplicate method 3 to get param BRepAdaptor_Curve adapt(e); const Handle_Geom_Curve c = adapt.Curve().Curve(); double maxDist = 0.000001; //magic number. less than this gives false positives. //bool found = (void) GeomLib_Tool::Parameter(c,pt,maxDist,param); //already know point it on curve result = true; } if (result) { TopoDS_Vertex v1 = TopExp::FirstVertex(e); TopoDS_Vertex v2 = TopExp::LastVertex(e); if (DrawUtil::isSamePoint(v,v1) || DrawUtil::isSamePoint(v,v2)) { if (!allowEnds) { result = false; } } } } //!outofbox return result; }
App::DocumentObjectExecReturn *DrawViewSection::execute(void) { App::DocumentObject* link = Source.getValue(); App::DocumentObject* base = BaseView.getValue(); if (!link || !base) { Base::Console().Log("INFO - DVS::execute - No Source or Link - creation?\n"); return DrawView::execute(); } if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) return new App::DocumentObjectExecReturn("Source object is not a Part object"); if (!base->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) return new App::DocumentObjectExecReturn("BaseView object is not a DrawViewPart object"); //Base::Console().Message("TRACE - DVS::execute() - %s/%s\n",getNameInDocument(),Label.getValue()); const Part::TopoShape &partTopo = static_cast<Part::Feature*>(link)->Shape.getShape(); if (partTopo.getShape().IsNull()) return new App::DocumentObjectExecReturn("Linked shape object is empty"); (void) DrawView::execute(); //make sure Scale is up to date gp_Pln pln = getSectionPlane(); gp_Dir gpNormal = pln.Axis().Direction(); Base::Vector3d orgPnt = SectionOrigin.getValue(); Base::BoundBox3d bb = partTopo.getBoundBox(); if(!isReallyInBox(orgPnt, bb)) { Base::Console().Warning("DVS: Section Plane doesn't intersect part in %s\n",getNameInDocument()); Base::Console().Warning("DVS: Using center of bounding box.\n"); orgPnt = bb.GetCenter(); SectionOrigin.setValue(orgPnt); } // Make the extrusion face double dMax = bb.CalcDiagonalLength(); BRepBuilderAPI_MakeFace mkFace(pln, -dMax,dMax,-dMax,dMax); TopoDS_Face aProjFace = mkFace.Face(); if(aProjFace.IsNull()) return new App::DocumentObjectExecReturn("DrawViewSection - Projected face is NULL"); gp_Vec extrudeDir = dMax * gp_Vec(gpNormal); TopoDS_Shape prism = BRepPrimAPI_MakePrism(aProjFace, extrudeDir, false, true).Shape(); // We need to copy the shape to not modify the BRepstructure BRepBuilderAPI_Copy BuilderCopy(partTopo.getShape()); TopoDS_Shape myShape = BuilderCopy.Shape(); BRepAlgoAPI_Cut mkCut(myShape, prism); if (!mkCut.IsDone()) return new App::DocumentObjectExecReturn("Section cut has failed"); TopoDS_Shape rawShape = mkCut.Shape(); Bnd_Box testBox; BRepBndLib::Add(rawShape, testBox); testBox.SetGap(0.0); if (testBox.IsVoid()) { //prism & input don't intersect. rawShape is garbage, don't bother. Base::Console().Log("INFO - DVS::execute - prism & input don't intersect\n"); return DrawView::execute(); } gp_Pnt inputCenter; try { inputCenter = TechDrawGeometry::findCentroid(rawShape, Direction.getValue()); TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(rawShape, inputCenter, Scale.getValue()); geometryObject = buildGeometryObject(mirroredShape,inputCenter); //this is original shape after cut by section prism #if MOD_TECHDRAW_HANDLE_FACES extractFaces(); #endif //#if MOD_TECHDRAW_HANDLE_FACES } catch (Standard_Failure) { Handle_Standard_Failure e1 = Standard_Failure::Caught(); Base::Console().Log("LOG - DVS::execute - base shape failed for %s - %s **\n",getNameInDocument(),e1->GetMessageString()); return new App::DocumentObjectExecReturn(e1->GetMessageString()); } try { TopoDS_Compound sectionCompound = findSectionPlaneIntersections(rawShape); TopoDS_Shape mirroredSection = TechDrawGeometry::mirrorShape(sectionCompound, inputCenter, Scale.getValue()); TopoDS_Compound newFaces; BRep_Builder builder; builder.MakeCompound(newFaces); TopExp_Explorer expl(mirroredSection, TopAbs_FACE); for (; expl.More(); expl.Next()) { const TopoDS_Face& face = TopoDS::Face(expl.Current()); TopoDS_Face pFace = projectFace(face, inputCenter, Direction.getValue()); if (!pFace.IsNull()) { builder.Add(newFaces,pFace); } } sectionFaces = newFaces; } catch (Standard_Failure) { Handle_Standard_Failure e2 = Standard_Failure::Caught(); Base::Console().Log("LOG - DVS::execute - failed building section faces for %s - %s **\n",getNameInDocument(),e2->GetMessageString()); return new App::DocumentObjectExecReturn(e2->GetMessageString()); } return App::DocumentObject::StdReturn; }
//! get the projected edges with all their new intersections. std::vector<TopoDS_Edge> DrawProjectSplit::getEdges(TechDrawGeometry::GeometryObject* geometryObject) { const std::vector<TechDrawGeometry::BaseGeom*>& goEdges = geometryObject->getVisibleFaceEdges(true,true); std::vector<TechDrawGeometry::BaseGeom*>::const_iterator itEdge = goEdges.begin(); std::vector<TopoDS_Edge> origEdges; for (;itEdge != goEdges.end(); itEdge++) { origEdges.push_back((*itEdge)->occEdge); } std::vector<TopoDS_Edge> faceEdges; std::vector<TopoDS_Edge> nonZero; for (auto& e:origEdges) { //drop any zero edges (shouldn't be any by now!!!) if (!DrawUtil::isZeroEdge(e)) { nonZero.push_back(e); } else { Base::Console().Message("INFO - DPS::getEdges found ZeroEdge!\n"); } } faceEdges = nonZero; origEdges = nonZero; //HLR algo does not provide all edge intersections for edge endpoints. //need to split long edges touched by Vertex of another edge std::vector<splitPoint> splits; std::vector<TopoDS_Edge>::iterator itOuter = origEdges.begin(); int iOuter = 0; for (; itOuter != origEdges.end(); ++itOuter, iOuter++) { TopoDS_Vertex v1 = TopExp::FirstVertex((*itOuter)); TopoDS_Vertex v2 = TopExp::LastVertex((*itOuter)); Bnd_Box sOuter; BRepBndLib::Add(*itOuter, sOuter); sOuter.SetGap(0.1); if (sOuter.IsVoid()) { Base::Console().Message("DPS::Extract Faces - outer Bnd_Box is void\n"); continue; } if (DrawUtil::isZeroEdge(*itOuter)) { Base::Console().Message("DPS::extractFaces - outerEdge: %d is ZeroEdge\n",iOuter); //this is not finding ZeroEdges continue; //skip zero length edges. shouldn't happen ;) } int iInner = 0; std::vector<TopoDS_Edge>::iterator itInner = faceEdges.begin(); for (; itInner != faceEdges.end(); ++itInner,iInner++) { if (iInner == iOuter) { continue; } if (DrawUtil::isZeroEdge((*itInner))) { continue; //skip zero length edges. shouldn't happen ;) } Bnd_Box sInner; BRepBndLib::Add(*itInner, sInner); sInner.SetGap(0.1); if (sInner.IsVoid()) { Base::Console().Log("INFO - DPS::Extract Faces - inner Bnd_Box is void\n"); continue; } if (sOuter.IsOut(sInner)) { //bboxes of edges don't intersect, don't bother continue; } double param = -1; if (isOnEdge((*itInner),v1,param,false)) { gp_Pnt pnt1 = BRep_Tool::Pnt(v1); splitPoint s1; s1.i = iInner; s1.v = Base::Vector3d(pnt1.X(),pnt1.Y(),pnt1.Z()); s1.param = param; splits.push_back(s1); } if (isOnEdge((*itInner),v2,param,false)) { gp_Pnt pnt2 = BRep_Tool::Pnt(v2); splitPoint s2; s2.i = iInner; s2.v = Base::Vector3d(pnt2.X(),pnt2.Y(),pnt2.Z()); s2.param = param; splits.push_back(s2); } } //inner loop } //outer loop std::vector<splitPoint> sorted = sortSplits(splits,true); auto last = std::unique(sorted.begin(), sorted.end(), DrawProjectSplit::splitEqual); //duplicates to back sorted.erase(last, sorted.end()); //remove dupls std::vector<TopoDS_Edge> newEdges = splitEdges(faceEdges,sorted); if (newEdges.empty()) { Base::Console().Log("LOG - DPS::extractFaces - no newEdges\n"); } newEdges = removeDuplicateEdges(newEdges); return newEdges; }
//======================================================================= //function : PreciseBoundingBox //purpose : //======================================================================= Standard_Boolean GEOMUtils::PreciseBoundingBox (const TopoDS_Shape &theShape, Bnd_Box &theBox) { if ( theBox.IsVoid() ) BRepBndLib::Add( theShape, theBox ); if ( theBox.IsVoid() ) return Standard_False; Standard_Real aBound[6]; theBox.Get(aBound[0], aBound[2], aBound[4], aBound[1], aBound[3], aBound[5]); Standard_Integer i; const gp_Pnt aMid(0.5*(aBound[1] + aBound[0]), // XMid 0.5*(aBound[3] + aBound[2]), // YMid 0.5*(aBound[5] + aBound[4])); // ZMid const gp_XYZ aSize(aBound[1] - aBound[0], // DX aBound[3] - aBound[2], // DY aBound[5] - aBound[4]); // DZ const gp_Pnt aPnt[6] = { gp_Pnt(aBound[0] - (aBound[1] - aBound[0]), aMid.Y(), aMid.Z()), // XMin gp_Pnt(aBound[1] + (aBound[1] - aBound[0]), aMid.Y(), aMid.Z()), // XMax gp_Pnt(aMid.X(), aBound[2] - (aBound[3] - aBound[2]), aMid.Z()), // YMin gp_Pnt(aMid.X(), aBound[3] + (aBound[3] - aBound[2]), aMid.Z()), // YMax gp_Pnt(aMid.X(), aMid.Y(), aBound[4] - (aBound[5] - aBound[4])), // ZMin gp_Pnt(aMid.X(), aMid.Y(), aBound[5] + (aBound[5] - aBound[4])) // ZMax }; const gp_Dir aDir[3] = { gp::DX(), gp::DY(), gp::DZ() }; const Standard_Real aPlnSize[3] = { 0.5*Max(aSize.Y(), aSize.Z()), // XMin, XMax planes 0.5*Max(aSize.X(), aSize.Z()), // YMin, YMax planes 0.5*Max(aSize.X(), aSize.Y()) // ZMin, ZMax planes }; gp_Pnt aPMin[2]; for (i = 0; i < 6; i++) { const Standard_Integer iHalf = i/2; const gp_Pln aPln(aPnt[i], aDir[iHalf]); BRepBuilderAPI_MakeFace aMkFace(aPln, -aPlnSize[iHalf], aPlnSize[iHalf], -aPlnSize[iHalf], aPlnSize[iHalf]); if (!aMkFace.IsDone()) { return Standard_False; } TopoDS_Shape aFace = aMkFace.Shape(); // Get minimal distance between planar face and shape. Standard_Real aMinDist = GEOMUtils::GetMinDistance(aFace, theShape, aPMin[0], aPMin[1]); if (aMinDist < 0.) { return Standard_False; } aBound[i] = aPMin[1].Coord(iHalf + 1); } // Update Bounding box with the new values. theBox.SetVoid(); theBox.Update(aBound[0], aBound[2], aBound[4], aBound[1], aBound[3], aBound[5]); return Standard_True; }
//! make faces from the existing edge geometry void DrawViewPart::extractFaces() { geometryObject->clearFaceGeom(); const std::vector<TechDrawGeometry::BaseGeom*>& goEdges = geometryObject->getVisibleFaceEdges(SmoothVisible.getValue(),SeamVisible.getValue()); std::vector<TechDrawGeometry::BaseGeom*>::const_iterator itEdge = goEdges.begin(); std::vector<TopoDS_Edge> origEdges; for (;itEdge != goEdges.end(); itEdge++) { origEdges.push_back((*itEdge)->occEdge); } std::vector<TopoDS_Edge> faceEdges; std::vector<TopoDS_Edge> nonZero; for (auto& e:origEdges) { //drop any zero edges (shouldn't be any by now!!!) if (!DrawUtil::isZeroEdge(e)) { nonZero.push_back(e); } else { Base::Console().Message("INFO - DVP::extractFaces for %s found ZeroEdge!\n",getNameInDocument()); } } faceEdges = nonZero; origEdges = nonZero; //HLR algo does not provide all edge intersections for edge endpoints. //need to split long edges touched by Vertex of another edge std::vector<splitPoint> splits; std::vector<TopoDS_Edge>::iterator itOuter = origEdges.begin(); int iOuter = 0; for (; itOuter != origEdges.end(); ++itOuter, iOuter++) { TopoDS_Vertex v1 = TopExp::FirstVertex((*itOuter)); TopoDS_Vertex v2 = TopExp::LastVertex((*itOuter)); Bnd_Box sOuter; BRepBndLib::Add(*itOuter, sOuter); sOuter.SetGap(0.1); if (sOuter.IsVoid()) { Base::Console().Message("DVP::Extract Faces - outer Bnd_Box is void for %s\n",getNameInDocument()); continue; } if (DrawUtil::isZeroEdge(*itOuter)) { Base::Console().Message("DVP::extractFaces - outerEdge: %d is ZeroEdge\n",iOuter); //this is not finding ZeroEdges continue; //skip zero length edges. shouldn't happen ;) } int iInner = 0; std::vector<TopoDS_Edge>::iterator itInner = faceEdges.begin(); for (; itInner != faceEdges.end(); ++itInner,iInner++) { if (iInner == iOuter) { continue; } if (DrawUtil::isZeroEdge((*itInner))) { continue; //skip zero length edges. shouldn't happen ;) } Bnd_Box sInner; BRepBndLib::Add(*itInner, sInner); sInner.SetGap(0.1); if (sInner.IsVoid()) { Base::Console().Log("INFO - DVP::Extract Faces - inner Bnd_Box is void for %s\n",getNameInDocument()); continue; } if (sOuter.IsOut(sInner)) { //bboxes of edges don't intersect, don't bother continue; } double param = -1; if (DrawProjectSplit::isOnEdge((*itInner),v1,param,false)) { gp_Pnt pnt1 = BRep_Tool::Pnt(v1); splitPoint s1; s1.i = iInner; s1.v = Base::Vector3d(pnt1.X(),pnt1.Y(),pnt1.Z()); s1.param = param; splits.push_back(s1); } if (DrawProjectSplit::isOnEdge((*itInner),v2,param,false)) { gp_Pnt pnt2 = BRep_Tool::Pnt(v2); splitPoint s2; s2.i = iInner; s2.v = Base::Vector3d(pnt2.X(),pnt2.Y(),pnt2.Z()); s2.param = param; splits.push_back(s2); } } //inner loop } //outer loop std::vector<splitPoint> sorted = DrawProjectSplit::sortSplits(splits,true); auto last = std::unique(sorted.begin(), sorted.end(), DrawProjectSplit::splitEqual); //duplicates to back sorted.erase(last, sorted.end()); //remove dupl splits std::vector<TopoDS_Edge> newEdges = DrawProjectSplit::splitEdges(faceEdges,sorted); if (newEdges.empty()) { Base::Console().Log("LOG - DVP::extractFaces - no newEdges\n"); return; } newEdges = DrawProjectSplit::removeDuplicateEdges(newEdges); //find all the wires in the pile of faceEdges EdgeWalker ew; ew.loadEdges(newEdges); bool success = ew.perform(); if (!success) { Base::Console().Warning("DVP::extractFaces - input is not planar graph. No face detection\n"); return; } std::vector<TopoDS_Wire> fw = ew.getResultNoDups(); std::vector<TopoDS_Wire> sortedWires = ew.sortStrip(fw,true); std::vector<TopoDS_Wire>::iterator itWire = sortedWires.begin(); for (; itWire != sortedWires.end(); itWire++) { //version 1: 1 wire/face - no voids in face TechDrawGeometry::Face* f = new TechDrawGeometry::Face(); const TopoDS_Wire& wire = (*itWire); TechDrawGeometry::Wire* w = new TechDrawGeometry::Wire(wire); f->wires.push_back(w); geometryObject->addFaceGeom(f); } }
App::DocumentObjectExecReturn *DrawViewDetail::execute(void) { if (!keepUpdated()) { return App::DocumentObject::StdReturn; } App::DocumentObject* baseObj = BaseView.getValue(); if (!baseObj) { Base::Console().Log("INFO - DVD::execute - No BaseView - creation?\n"); return DrawView::execute(); } DrawViewPart* dvp = nullptr; if (!baseObj->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) { return new App::DocumentObjectExecReturn("BaseView object is not a DrawViewPart object"); } else { dvp = static_cast<DrawViewPart*>(baseObj); } TopoDS_Shape shape = dvp->getSourceShapeFused(); if (shape.IsNull()) { return new App::DocumentObjectExecReturn("DVD - Linked shape object is invalid"); } Base::Vector3d anchor = AnchorPoint.getValue(); //this is a 2D point (in unrotated coords) Base::Vector3d dirDetail = dvp->Direction.getValue(); double shapeRotate = dvp->Rotation.getValue(); //degrees CW? if (dvp->isDerivedFrom(TechDraw::DrawProjGroupItem::getClassTypeId())) { DrawProjGroupItem* dpgi= static_cast<TechDraw::DrawProjGroupItem*>(dvp); shapeRotate += dpgi->getRotateAngle() * 180.0/M_PI; // to degrees from radians } double radius = getFudgeRadius(); double scale = getScale(); BRepBuilderAPI_Copy BuilderCopy(shape); TopoDS_Shape myShape = BuilderCopy.Shape(); //rotate the copied shape to match orientation of BaseView and center it on origin gp_Pnt gpCenter = TechDrawGeometry::findCentroid(myShape, //centre of unrotated shape dirDetail); Base::Vector3d shapeCenter = Base::Vector3d(gpCenter.X(),gpCenter.Y(),gpCenter.Z()); gp_Ax2 viewAxis = getViewAxis(shapeCenter, dirDetail, false); myShape = TechDrawGeometry::rotateShape(myShape, //rotate to match Base shape viewAxis, -shapeRotate); myShape = TechDrawGeometry::moveShape(myShape, //centre on origin -shapeCenter); // shapeCenter = Base::Vector3d(0.0,0.0,0.0); gpCenter = TechDrawGeometry::findCentroid(myShape, dirDetail); shapeCenter = Base::Vector3d(gpCenter.X(),gpCenter.Y(),gpCenter.Z()); Bnd_Box bbxSource; bbxSource.SetGap(0.0); BRepBndLib::Add(myShape, bbxSource); double diag = sqrt(bbxSource.SquareExtent()); Base::Vector3d extentFar,extentNear; extentFar = shapeCenter + dirDetail * diag; extentNear = shapeCenter + dirDetail * diag * -1.0; anchor = Base::Vector3d(anchor.x,anchor.y, 0.0); viewAxis = getViewAxis(shapeCenter, dirDetail, false); //change view axis to (0,0,0) Base::Vector3d offsetCenter3D = DrawUtil::toR3(viewAxis, anchor); //displacement in R3 Base::Vector3d stdZ(0.0,0.0,1.0); if (DrawUtil::checkParallel(dirDetail,stdZ)) { extentNear = extentNear + offsetCenter3D; } else { extentNear = extentNear - offsetCenter3D; } gp_Dir cylDir(dirDetail.x,dirDetail.y,dirDetail.z); gp_Pnt cylPoint(extentNear.x,extentNear.y,extentNear.z); gp_Ax2 cylAxis(cylPoint,cylDir); BRepPrimAPI_MakeCylinder mkCyl(cylAxis, radius, (extentFar-extentNear).Length()); TopoDS_Shell sh = mkCyl.Cylinder().Shell(); BRepBuilderAPI_MakeSolid mkSol(sh); TopoDS_Solid tool = mkSol.Solid(); BRepAlgoAPI_Common mkCommon(myShape,tool); if (!mkCommon.IsDone()) { Base::Console().Log("DVD::execute - mkCommon not done\n"); return new App::DocumentObjectExecReturn("DVD::execute - mkCommon not done"); } if (mkCommon.Shape().IsNull()) { Base::Console().Log("DVD::execute - mkCommon.Shape is Null\n"); return new App::DocumentObjectExecReturn("DVD::execute - mkCommon.Shape is Null"); } //Did we get a solid? TopExp_Explorer xp; xp.Init(mkCommon.Shape(),TopAbs_SOLID); if (!(xp.More() == Standard_True)) { Base::Console().Message("DVD::execute - mkCommon.Shape is not a solid!\n"); } TopoDS_Shape detail = mkCommon.Shape(); Bnd_Box testBox; testBox.SetGap(0.0); BRepBndLib::Add(detail, testBox); if (testBox.IsVoid()) { Base::Console().Message("DrawViewDetail - detail area contains no geometry\n"); return new App::DocumentObjectExecReturn("DVDetail - detail area contains no geometry"); } //for debugging show compound instead of common // BRep_Builder builder; // TopoDS_Compound Comp; // builder.MakeCompound(Comp); // builder.Add(Comp, tool); // builder.Add(Comp, myShape); gp_Pnt inputCenter; try { inputCenter = TechDrawGeometry::findCentroid(tool, Direction.getValue()); TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(detail, inputCenter, scale); viewAxis = getViewAxis(Base::Vector3d(inputCenter.X(),inputCenter.Y(),inputCenter.Z()),Direction.getValue()); if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) { mirroredShape = TechDrawGeometry::rotateShape(mirroredShape, viewAxis, Rotation.getValue()); //degrees cw? } geometryObject = buildGeometryObject(mirroredShape,viewAxis); geometryObject->pruneVertexGeom(Base::Vector3d(0.0,0.0,0.0),Radius.getValue() * scale); //remove vertices beyond clipradius #if MOD_TECHDRAW_HANDLE_FACES if (handleFaces()) { try { extractFaces(); } catch (Standard_Failure& e4) { Base::Console().Log("LOG - DVD::execute - extractFaces failed for %s - %s **\n",getNameInDocument(),e4.GetMessageString()); return new App::DocumentObjectExecReturn(e4.GetMessageString()); } } #endif //#if MOD_TECHDRAW_HANDLE_FACES } catch (Standard_Failure& e1) { Base::Console().Log("LOG - DVD::execute - base shape failed for %s - %s **\n",getNameInDocument(),e1.GetMessageString()); return new App::DocumentObjectExecReturn(e1.GetMessageString()); } requestPaint(); dvp->requestPaint(); return App::DocumentObject::StdReturn; }
//this routine is the big time consumer. gets called many times (and is slow?)) //note param gets modified here bool DrawViewPart::isOnEdge(TopoDS_Edge e, TopoDS_Vertex v, double& param, bool allowEnds) { bool result = false; bool outOfBox = false; param = -2; //eliminate obvious cases Bnd_Box sBox; BRepBndLib::Add(e, sBox); sBox.SetGap(0.1); if (sBox.IsVoid()) { Base::Console().Message("DVP::isOnEdge - Bnd_Box is void for %s\n",getNameInDocument()); } else { gp_Pnt pt = BRep_Tool::Pnt(v); if (sBox.IsOut(pt)) { outOfBox = true; } } if (!outOfBox) { if (m_interAlgo == 1) { //1) using projPointOnCurve. roughly similar to dist to shape w/ bndbox. hangs(?) w/o bndbox try { gp_Pnt pt = BRep_Tool::Pnt(v); BRepAdaptor_Curve adapt(e); Handle_Geom_Curve c = adapt.Curve().Curve(); GeomAPI_ProjectPointOnCurve proj(pt,c); int n = proj.NbPoints(); if (n > 0) { if (proj.LowerDistance() < Precision::Confusion()) { param = proj.LowerDistanceParameter(); result = true; } if (result) { TopoDS_Vertex v1 = TopExp::FirstVertex(e); TopoDS_Vertex v2 = TopExp::LastVertex(e); if (DrawUtil::isSamePoint(v,v1) || DrawUtil::isSamePoint(v,v2)) { if (!allowEnds) { result = false; } } } } } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); //no perp projection } } else if (m_interAlgo == 2) { //can't provide param as is double dist = simpleMinDist(v,e); if (dist < 0.0) { Base::Console().Error("DVP::isOnEdge - simpleMinDist failed: %.3f\n",dist); result = false; } else if (dist < Precision::Confusion()) { const gp_Pnt pt = BRep_Tool::Pnt(v); //have to duplicate method 3 to get param BRepAdaptor_Curve adapt(e); const Handle_Geom_Curve c = adapt.Curve().Curve(); double maxDist = 0.000001; //magic number. less than this gives false positives. //bool found = (void) GeomLib_Tool::Parameter(c,pt,maxDist,param); //already know point it on curve result = true; } if (result) { TopoDS_Vertex v1 = TopExp::FirstVertex(e); TopoDS_Vertex v2 = TopExp::LastVertex(e); if (DrawUtil::isSamePoint(v,v1) || DrawUtil::isSamePoint(v,v2)) { if (!allowEnds) { result = false; } } } } else if (m_interAlgo == 3) { const gp_Pnt pt = BRep_Tool::Pnt(v); BRepAdaptor_Curve adapt(e); const Handle_Geom_Curve c = adapt.Curve().Curve(); double par = -1; double maxDist = 0.000001; //magic number. less than this gives false positives. bool found = GeomLib_Tool::Parameter(c,pt,maxDist,par); if (found) { result = true; param = par; TopoDS_Vertex v1 = TopExp::FirstVertex(e); TopoDS_Vertex v2 = TopExp::LastVertex(e); if (DrawUtil::isSamePoint(v,v1) || DrawUtil::isSamePoint(v,v2)) { if (!allowEnds) { result = false; } } } } } //!outofbox return result; }