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; }
std::vector<TopoDS_Wire> EdgeWalker::sortStrip(std::vector<TopoDS_Wire> fw, bool includeBiggest) { std::vector<TopoDS_Wire> sortedWires = sortWiresBySize(fw,false); //biggest 1st if (!sortedWires.size()) { Base::Console().Log("INFO - DVP::extractFaces - no sorted Wires!\n"); return sortedWires; // might happen in the middle of changes? } //find the largest wire (OuterWire of graph) using bbox Bnd_Box bigBox; if (sortedWires.size() && !sortedWires.front().IsNull()) { BRepBndLib::Add(sortedWires.front(), bigBox); bigBox.SetGap(0.0); } std::vector<std::size_t> toBeChecked; std::vector<TopoDS_Wire>::iterator it = sortedWires.begin() + 1; for (; it != sortedWires.end(); it++) { if (!(*it).IsNull()) { Bnd_Box littleBox; BRepBndLib::Add((*it), littleBox); littleBox.SetGap(0.0); if (bigBox.SquareExtent() > littleBox.SquareExtent()) { break; } else { auto position = std::distance( sortedWires.begin(), it ); //get an index from iterator toBeChecked.push_back(position); } } } //unfortuneately, faces can have same bbox, but not be same size. need to weed out biggest if (toBeChecked.size() == 0) { //nobody had as big a bbox as first element of sortedWires if (!includeBiggest) { sortedWires.erase(sortedWires.begin()); } } else if (toBeChecked.size() > 0) { BRepBuilderAPI_MakeFace mkFace(sortedWires.front()); const TopoDS_Face& face = mkFace.Face(); GProp_GProps props; BRepGProp::SurfaceProperties(face, props); double bigArea = props.Mass(); unsigned int bigIndex = 0; for (unsigned int idx = 0; idx < toBeChecked.size(); idx++) { int iCheck = toBeChecked.at(idx); BRepBuilderAPI_MakeFace mkFace2(sortedWires.at(iCheck)); const TopoDS_Face& face2 = mkFace2.Face(); BRepGProp::SurfaceProperties(face2, props); double area = props.Mass(); if (area > bigArea) { bigArea = area; bigIndex = iCheck; } } if (bigIndex == 0) { //first wire is the biggest if (!includeBiggest) { sortedWires.erase(sortedWires.begin()); } } else { //first wire is not the biggest TopoDS_Wire bigWire = *(sortedWires.begin() + bigIndex); sortedWires.erase(sortedWires.begin() + bigIndex); if (includeBiggest) { sortedWires.insert(sortedWires.begin(),bigWire); //doesn't happen often } } } return sortedWires; }