/*************************************************************************** * Copyright (c) WandererFan (wandererfan@gmail.com) 2016 * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #include "PreCompiled.h" #ifndef _PreComp_ # include #include #include #include #include #include #include #include # include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif #include # include # include #include #include #include #include #include #include #include #include "Geometry.h" #include "GeometryObject.h" #include "EdgeWalker.h" #include "DrawProjectSplit.h" #include "DrawUtil.h" #include "DrawViewDetail.h" using namespace TechDraw; using namespace std; //=========================================================================== // DrawViewDetail //=========================================================================== PROPERTY_SOURCE(TechDraw::DrawViewDetail, TechDraw::DrawViewPart) DrawViewDetail::DrawViewDetail() : m_mattingStyle(0) { static const char *dgroup = "Detail"; ADD_PROPERTY_TYPE(BaseView ,(0),dgroup,App::Prop_None,"2D View source for this Section"); ADD_PROPERTY_TYPE(AnchorPoint ,(0,0,0) ,dgroup,App::Prop_None,"Location of detail in BaseView"); ADD_PROPERTY_TYPE(Radius,(10.0),dgroup, App::Prop_None, "Size of detail area"); ADD_PROPERTY_TYPE(Reference ,("1"),dgroup,App::Prop_None,"An identifier for this detail"); getParameters(); } DrawViewDetail::~DrawViewDetail() { } short DrawViewDetail::mustExecute() const { short result = 0; if (!isRestoring()) { result = (AnchorPoint.isTouched() || Radius.isTouched() || BaseView.isTouched() || Reference.isTouched()); } if (result) { return result; } return TechDraw::DrawView::mustExecute(); } void DrawViewDetail::onChanged(const App::Property* prop) { if (!isRestoring()) { //Base::Console().Message("TRACE - DVD::onChanged(%s) - %s\n",prop->getName(),Label.getValue()); if (prop == &Reference) { std::string lblText = "Detail " + std::string(Reference.getValue()); Label.setValue(lblText); } } DrawView::onChanged(prop); } App::DocumentObjectExecReturn *DrawViewDetail::execute(void) { App::DocumentObject* link = Source.getValue(); App::DocumentObject* base = BaseView.getValue(); if (!link || !base) { Base::Console().Log("INFO - DVD::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"); DrawViewPart* dvp = nullptr; if (!base->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) { return new App::DocumentObjectExecReturn("BaseView object is not a DrawViewPart object"); } else { dvp = static_cast(base); } //Base::Console().Message("TRACE - DVD::execute() - %s/%s\n",getNameInDocument(),Label.getValue()); const Part::TopoShape &partTopo = static_cast(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 Base::Vector3d anchor = AnchorPoint.getValue(); //this is a 2D point anchor = Base::Vector3d(anchor.x,anchor.y, 0.0); double radiusFudge = 1.1; double radius = Radius.getValue() * radiusFudge; Base::Vector3d dirDetail = dvp->Direction.getValue(); double scale = Scale.getValue(); gp_Ax2 viewAxis = TechDrawGeometry::getViewAxis(Base::Vector3d(0.0,0.0,0.0), dirDetail, false); Base::BoundBox3d bbxSource = partTopo.getBoundBox(); BRepBuilderAPI_Copy BuilderCopy(partTopo.getShape()); TopoDS_Shape myShape = BuilderCopy.Shape(); gp_Pnt gpCenter = TechDrawGeometry::findCentroid(myShape, dirDetail); Base::Vector3d shapeCenter = Base::Vector3d(gpCenter.X(),gpCenter.Y(),gpCenter.Z()); double diag = bbxSource.CalcDiagonalLength(); Base::Vector3d extentFar,extentNear; extentFar = shapeCenter + dirDetail * diag; extentNear = shapeCenter + dirDetail * diag * -1.0; //turn anchor(x,y,0) in projection plane(P) into displacement in 3D Base::Vector3d offsetCenter3D = DrawUtil::toR3(viewAxis, anchor); //displacement in R3 if (DrawUtil::checkZParallel(dirDetail)) { 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().Message("TRACE - DVD::execute - mkCommon not done\n"); return new App::DocumentObjectExecReturn("DVD::execute - mkCommon not done"); } if (mkCommon.Shape().IsNull()) { Base::Console().Message("TRACE - 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("TRACE - 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("INFO - DVD::execute - testBox is void\n"); } //for debugging show compound instead of cut // BRep_Builder builder; // TopoDS_Compound Comp; // builder.MakeCompound(Comp); // builder.Add(Comp, tool); // builder.Add(Comp, myShape); gp_Pnt inputCenter; try { inputCenter = TechDrawGeometry::findCentroid(detail, Direction.getValue()); TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(detail, inputCenter, scale); geometryObject = buildGeometryObject(mirroredShape,inputCenter); #if MOD_TECHDRAW_HANDLE_FACES if (handleFaces()) { try { extractFaces(); } catch (Standard_Failure) { Handle_Standard_Failure e4 = Standard_Failure::Caught(); 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) { Handle_Standard_Failure e1 = Standard_Failure::Caught(); Base::Console().Log("LOG - DVD::execute - base shape failed for %s - %s **\n",getNameInDocument(),e1->GetMessageString()); return new App::DocumentObjectExecReturn(e1->GetMessageString()); } return App::DocumentObject::StdReturn; } void DrawViewDetail::getParameters() { // what parameters are useful? // handleFaces // radiusFudge? Base::Reference hGrp = App::GetApplication().GetUserParameter() .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw"); m_mattingStyle = hGrp->GetInt("MattingStyle", 0); } // Python Drawing feature --------------------------------------------------------- namespace App { /// @cond DOXERR PROPERTY_SOURCE_TEMPLATE(TechDraw::DrawViewDetailPython, TechDraw::DrawViewDetail) template<> const char* TechDraw::DrawViewDetailPython::getViewProviderName(void) const { return "TechDrawGui::ViewProviderViewPart"; } /// @endcond // explicit template instantiation template class TechDrawExport FeaturePythonT; }