From 4cb4e5f04a77da89721a1bb7e3725059e498820c Mon Sep 17 00:00:00 2001 From: WandererFan Date: Mon, 22 Aug 2016 11:14:09 -0400 Subject: [PATCH] Create ViewSection from ViewPart Property name changes Touch section when View SymbolSection changes --- src/Mod/TechDraw/App/DrawViewPart.cpp | 102 ++++++- src/Mod/TechDraw/App/DrawViewPart.h | 24 +- src/Mod/TechDraw/App/DrawViewSection.cpp | 103 ++++--- src/Mod/TechDraw/App/DrawViewSection.h | 2 + src/Mod/TechDraw/Gui/CMakeLists.txt | 10 + src/Mod/TechDraw/Gui/Command.cpp | 32 ++- src/Mod/TechDraw/Gui/QGCustomText.cpp | 1 + src/Mod/TechDraw/Gui/QGIDecoration.cpp | 85 ++++++ src/Mod/TechDraw/Gui/QGIDecoration.h | 67 +++++ src/Mod/TechDraw/Gui/QGIFace.cpp | 3 +- src/Mod/TechDraw/Gui/QGISectionLine.cpp | 215 +++++++++++++++ src/Mod/TechDraw/Gui/QGISectionLine.h | 87 ++++++ src/Mod/TechDraw/Gui/QGIUserTypes.h | 49 ++++ src/Mod/TechDraw/Gui/QGIView.cpp | 2 +- src/Mod/TechDraw/Gui/QGIViewPart.cpp | 94 ++++++- src/Mod/TechDraw/Gui/QGIViewPart.h | 3 + src/Mod/TechDraw/Gui/QGIViewSection.cpp | 5 + src/Mod/TechDraw/Gui/QGIViewSection.h | 2 + src/Mod/TechDraw/Gui/TaskSectionView.cpp | 324 +++++++++++++++++++++++ src/Mod/TechDraw/Gui/TaskSectionView.h | 122 +++++++++ src/Mod/TechDraw/Gui/TaskSectionView.ui | 303 +++++++++++++++++++++ src/Mod/TechDraw/Gui/ZVALUE.h | 11 +- 22 files changed, 1594 insertions(+), 52 deletions(-) create mode 100644 src/Mod/TechDraw/Gui/QGIDecoration.cpp create mode 100644 src/Mod/TechDraw/Gui/QGIDecoration.h create mode 100644 src/Mod/TechDraw/Gui/QGISectionLine.cpp create mode 100644 src/Mod/TechDraw/Gui/QGISectionLine.h create mode 100644 src/Mod/TechDraw/Gui/QGIUserTypes.h create mode 100644 src/Mod/TechDraw/Gui/TaskSectionView.cpp create mode 100644 src/Mod/TechDraw/Gui/TaskSectionView.h create mode 100644 src/Mod/TechDraw/Gui/TaskSectionView.ui diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index b8b18ac8f..2d594e1ad 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include #include #include @@ -66,6 +68,7 @@ #include #include +#include "DrawViewSection.h" #include "Geometry.h" #include "GeometryObject.h" #include "DrawViewPart.h" @@ -91,6 +94,7 @@ DrawViewPart::DrawViewPart(void) : geometryObject(0) { static const char *group = "Projection"; static const char *fgroup = "Format"; + static const char *lgroup = "SectionLine"; ADD_PROPERTY_TYPE(Direction ,(0,0,1.0) ,group,App::Prop_None,"Projection normal direction"); ADD_PROPERTY_TYPE(Source ,(0),group,App::Prop_None,"3D Shape to view"); @@ -100,12 +104,19 @@ DrawViewPart::DrawViewPart(void) : geometryObject(0) //ADD_PROPERTY_TYPE(ShowIsoLines ,(false),group,App::Prop_None,"Iso u,v lines on/off"); ADD_PROPERTY_TYPE(Tolerance,(0.05f),group,App::Prop_None,"Internal tolerance"); Tolerance.setConstraints(&floatRange); - ADD_PROPERTY_TYPE(XAxisDirection ,(1,0,0) ,group,App::Prop_None,"Direction to use as X-axis in projection"); + ADD_PROPERTY_TYPE(XAxisDirection ,(1,0,0) ,group,App::Prop_None,"Where to place projection XAxis in display"); + ADD_PROPERTY_TYPE(LineWidth,(0.7f),fgroup,App::Prop_None,"The thickness of visible lines"); ADD_PROPERTY_TYPE(HiddenWidth,(0.15),fgroup,App::Prop_None,"The thickness of hidden lines, if enabled"); ADD_PROPERTY_TYPE(ShowCenters ,(true),fgroup,App::Prop_None,"Center marks on/off"); ADD_PROPERTY_TYPE(CenterScale,(2.0),fgroup,App::Prop_None,"Center mark size adjustment, if enabled"); + ADD_PROPERTY_TYPE(ShowSectionLine ,(true) ,lgroup,App::Prop_None,"Show/hide section line if applicable"); + ADD_PROPERTY_TYPE(HorizSectionLine ,(true) ,lgroup,App::Prop_None,"Section line is horizontal"); + ADD_PROPERTY_TYPE(ArrowUpSection ,(true) ,lgroup,App::Prop_None,"Section line arrows point up"); + ADD_PROPERTY_TYPE(SymbolSection,("A") ,lgroup,App::Prop_None,"Section identifier"); + + geometryObject = new TechDrawGeometry::GeometryObject(); } @@ -143,6 +154,7 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void) gp_Pnt inputCenter = TechDrawGeometry::findCentroid(shape, Direction.getValue(), getValidXDir()); + shapeCentroid = Base::Vector3d(inputCenter.X(),inputCenter.Y(),inputCenter.Z()); TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(shape, inputCenter, Scale.getValue()); @@ -188,6 +200,9 @@ short DrawViewPart::mustExecute() const void DrawViewPart::onChanged(const App::Property* prop) { if (!isRestoring()) { + if (prop == &SymbolSection && getSectionRef()) { + getSectionRef()->touch(); + } if (prop == &Direction || prop == &XAxisDirection || prop == &Source || @@ -199,7 +214,11 @@ void DrawViewPart::onChanged(const App::Property* prop) prop == &LineWidth || prop == &HiddenWidth || prop == &ShowCenters || - prop == &CenterScale ) { + prop == &CenterScale || + prop == &ShowSectionLine || + prop == &HorizSectionLine || + prop == &ArrowUpSection || + prop == &SymbolSection ) { try { App::DocumentObjectExecReturn *ret = recompute(); delete ret; @@ -215,6 +234,11 @@ void DrawViewPart::onChanged(const App::Property* prop) void DrawViewPart::buildGeometryObject(TopoDS_Shape shape, gp_Pnt& inputCenter) { + Base::Vector3d baseProjDir = Direction.getValue(); + + saveParamSpace(baseProjDir, + getValidXDir()); + geometryObject->projectShape(shape, inputCenter, Direction.getValue(), @@ -589,7 +613,7 @@ Base::BoundBox3d DrawViewPart::getBoundingBox() const double DrawViewPart::getBoxX(void) const { - Base::BoundBox3d bbx = getBoundingBox(); //bbox is already scaled + Base::BoundBox3d bbx = getBoundingBox(); //bbox is already scaled & centered! return (bbx.MaxX - bbx.MinX); } @@ -605,6 +629,22 @@ QRectF DrawViewPart::getRect() const return result; } +//used to project pt (ex SectionOrigin) onto paper plane +Base::Vector3d DrawViewPart::projectPoint(Base::Vector3d pt) const +{ + Base::Vector3d centeredPoint = pt - shapeCentroid; + Base::Vector3d direction = Direction.getValue(); + Base::Vector3d xAxis = getValidXDir(); + gp_Ax2 viewAxis; + viewAxis = gp_Ax2(gp_Pnt(0.0,0.0,0.0), + gp_Dir(direction.x, direction.y, direction.z), + gp_Dir(xAxis.x, xAxis.y, xAxis.z)); + HLRAlgo_Projector projector( viewAxis ); + gp_Pnt2d prjPnt; + projector.Project(gp_Pnt(centeredPoint.x,centeredPoint.y,centeredPoint.z), prjPnt); + return Base::Vector3d(prjPnt.X(),prjPnt.Y(), 0.0); +} + //! make a clean wire with sorted, oriented, connected, etc edges @@ -708,6 +748,33 @@ Base::Vector3d DrawViewPart::getValidXDir() const return xDir; } +void DrawViewPart::saveParamSpace(Base::Vector3d direction, + Base::Vector3d xAxis) +{ + gp_Ax2 viewAxis; + viewAxis = gp_Ax2(gp_Pnt(0, 0, 0), + gp_Dir(direction.x, -direction.y, direction.z), + gp_Dir(xAxis.x, -xAxis.y, xAxis.z)); // Y invert warning! // + + uDir = Base::Vector3d(xAxis.x, -xAxis.y, xAxis.z); + gp_Dir ydir = viewAxis.YDirection(); + vDir = Base::Vector3d(ydir.X(),ydir.Y(),ydir.Z()); + wDir = Base::Vector3d(direction.x, -direction.y, direction.z); +} + + +DrawViewSection* DrawViewPart::getSectionRef(void) const +{ + DrawViewSection* result = nullptr; + std::vector inObjs = getInList(); + for (auto& o:inObjs) { + if (o->getTypeId().isDerivedFrom(DrawViewSection::getClassTypeId())) { + result = static_cast(o); + } + } + return result; +} + void DrawViewPart::dumpVertexes(const char* text, const TopoDS_Shape& s) { Base::Console().Message("DUMP - %s\n",text); @@ -720,6 +787,35 @@ void DrawViewPart::dumpVertexes(const char* text, const TopoDS_Shape& s) } } +void DrawViewPart::countFaces(const char* text, const TopoDS_Shape& s) +{ + TopExp_Explorer expl(s, TopAbs_FACE); + int i; + for (i = 0 ; expl.More(); expl.Next(),i++) { + } + Base::Console().Message("COUNT - %s has %d Faces\n",text,i); +} + +void DrawViewPart::countWires(const char* text, const TopoDS_Shape& s) +{ + TopExp_Explorer expl(s, TopAbs_WIRE); + int i = 0; + for (; expl.More(); expl.Next()) { + i++; + } + Base::Console().Message("COUNT - %s has %d wires\n",text,i); +} + +void DrawViewPart::countEdges(const char* text, const TopoDS_Shape& s) +{ + TopExp_Explorer expl(s, TopAbs_EDGE); + int i = 0; + for (; expl.More(); expl.Next()) { + i++; + } + Base::Console().Message("COUNT - %s has %d edges\n",text,i); +} + void DrawViewPart::dump1Vertex(const char* text, const TopoDS_Vertex& v) { Base::Console().Message("DUMP - DVP::dump1Vertex - %s\n",text); diff --git a/src/Mod/TechDraw/App/DrawViewPart.h b/src/Mod/TechDraw/App/DrawViewPart.h index 809e7f057..85e643793 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.h +++ b/src/Mod/TechDraw/App/DrawViewPart.h @@ -52,6 +52,7 @@ struct WalkerEdge; namespace TechDraw { +class DrawViewSection; class TechDrawExport DrawViewPart : public DrawView { @@ -74,6 +75,12 @@ public: App::PropertyFloat CenterScale; App::PropertyFloatConstraint Tolerance; + App::PropertyBool ShowSectionLine; + App::PropertyBool HorizSectionLine; //true(horiz)/false(vert) + App::PropertyBool ArrowUpSection; //true(up/right)/false(down/left) + App::PropertyString SymbolSection; + + std::vector getHatches(void) const; //TODO: are there use-cases for Python access to TechDrawGeometry??? @@ -90,6 +97,10 @@ public: double getBoxX(void) const; double getBoxY(void) const; virtual QRectF getRect() const; + virtual DrawViewSection* getSectionRef() const; //is there a ViewSection based on this ViewPart? + Base::Vector3d getUDir(void) {return uDir;} //paperspace X + Base::Vector3d getVDir(void) {return vDir;} //paperspace Y + Base::Vector3d getWDir(void) {return wDir;} //paperspace Z short mustExecute() const; @@ -109,13 +120,17 @@ public: void dumpVertexes(const char* text, const TopoDS_Shape& s); void dumpEdge(char* label, int i, TopoDS_Edge e); void dump1Vertex(const char* label, const TopoDS_Vertex& v); + void countFaces(const char* label, const TopoDS_Shape& s); + void countWires(const char* label, const TopoDS_Shape& s); + void countEdges(const char* label, const TopoDS_Shape& s); + Base::Vector3d getValidXDir() const; + Base::Vector3d projectPoint(Base::Vector3d pt) const; protected: TechDrawGeometry::GeometryObject *geometryObject; Base::BoundBox3d bbox; void onChanged(const App::Property* prop); - Base::Vector3d getValidXDir() const; void buildGeometryObject(TopoDS_Shape shape, gp_Pnt& center); void extractFaces(); std::vector sortWiresBySize(std::vector& w, bool reverse = false); @@ -131,6 +146,13 @@ protected: std::vector verts); TopoDS_Wire makeCleanWire(std::vector edges, double tol = 0.10); + //Projection parameter space + void saveParamSpace(Base::Vector3d direction, + Base::Vector3d xAxis); + Base::Vector3d uDir; //paperspace X + Base::Vector3d vDir; //paperspace Y + Base::Vector3d wDir; //paperspace Z + Base::Vector3d shapeCentroid; private: static App::PropertyFloatConstraint::Constraints floatRange; diff --git a/src/Mod/TechDraw/App/DrawViewSection.cpp b/src/Mod/TechDraw/App/DrawViewSection.cpp index f912ab595..4562f0fcf 100644 --- a/src/Mod/TechDraw/App/DrawViewSection.cpp +++ b/src/Mod/TechDraw/App/DrawViewSection.cpp @@ -1,6 +1,7 @@ /*************************************************************************** * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 * * Copyright (c) Luke Parry (l.parry@warwick.ac.uk) 2013 * + * Copyright (c) WandererFan (wandererfan@gmail.com) 2016 * * * * This file is part of the FreeCAD CAx development system. * * * @@ -77,17 +78,19 @@ PROPERTY_SOURCE(TechDraw::DrawViewSection, TechDraw::DrawViewPart) DrawViewSection::DrawViewSection() { - static const char *group = "Section"; + static const char *sgroup = "Section"; + static const char *lgroup = "Line"; Base::Reference hGrp = App::GetApplication().GetUserParameter() .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Colors"); App::Color fcColor = App::Color((uint32_t) hGrp->GetUnsigned("CutSurfaceColor", 0xC8C8C800)); + ADD_PROPERTY_TYPE(SectionNormal ,(0,0,1.0) ,sgroup,App::Prop_None,"Section Plane normal direction"); + ADD_PROPERTY_TYPE(SectionOrigin ,(0,0,0) ,sgroup,App::Prop_None,"Section Plane Origin"); + ADD_PROPERTY_TYPE(ShowCutSurface ,(true),sgroup,App::Prop_None,"Show the cut surface"); + ADD_PROPERTY_TYPE(CutSurfaceColor,(fcColor),sgroup,App::Prop_None,"The color to shade the cut surface"); - ADD_PROPERTY_TYPE(SectionNormal ,(0,0,1.0) ,group,App::Prop_None,"Section Plane normal direction"); - ADD_PROPERTY_TYPE(SectionOrigin ,(0,0,0) ,group,App::Prop_None,"Section Plane Origin"); - ADD_PROPERTY_TYPE(ShowCutSurface ,(true),group,App::Prop_None,"Show the cut surface"); - ADD_PROPERTY_TYPE(CutSurfaceColor,(fcColor),group,App::Prop_None,"The color to shade the cut surface"); + ADD_PROPERTY_TYPE(BaseView ,(0),lgroup,App::Prop_None,"2D View with SectionLine"); geometryObject = new TechDrawGeometry::GeometryObject(); } @@ -110,16 +113,20 @@ short DrawViewSection::mustExecute() const App::DocumentObjectExecReturn *DrawViewSection::execute(void) { - //## Get the Part Link ##/ App::DocumentObject* link = Source.getValue(); - - if (!link) - return new App::DocumentObjectExecReturn("No object linked"); + 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("Linked object is not a Part object"); + 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"); const Part::TopoShape &partTopo = static_cast(link)->Shape.getShape(); + const TechDraw::DrawViewPart* dvp = static_cast(base); if (partTopo.getShape().IsNull()) return new App::DocumentObjectExecReturn("Linked shape object is empty"); @@ -129,13 +136,14 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void) gp_XYZ xAxis = pln.XAxis().Direction().XYZ(); gp_XYZ yAxis = pln.YAxis().Direction().XYZ(); gp_XYZ origin = pln.Location().XYZ(); + gp_Dir plnNormal = pln.Axis().Direction().XYZ(); Base::BoundBox3d bb = partTopo.getBoundBox(); Base::Vector3d tmp1 = SectionOrigin.getValue(); Base::Vector3d plnPnt(tmp1.x, tmp1.y, tmp1.z); - Base::Vector3d tmp2 = SectionNormal.getValue(); - Base::Vector3d plnNorm(tmp2.x, tmp2.y, tmp2.z); + //Base::Vector3d tmp2 = SectionNormal.getValue(); + Base::Vector3d plnNorm(plnNormal.X(), plnNormal.Y(), plnNormal.Z()); // if(!bb.IsCutPlane(plnPnt, plnNorm)) { //this test doesn't work if plane is coincident with bb! if(!isReallyInBox(plnPnt, bb)) { @@ -212,6 +220,7 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void) inputCenter, Scale.getValue()); buildGeometryObject(mirroredShape,inputCenter); //this is original shape after cut by section prism + #if MOD_TECHDRAW_HANDLE_FACES extractFaces(); #endif //#if MOD_TECHDRAW_HANDLE_FACES @@ -220,6 +229,7 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void) TopoDS_Shape mirroredSection = TechDrawGeometry::mirrorShape(sectionCompound, inputCenter, Scale.getValue()); + TopoDS_Compound newFaces; BRep_Builder builder; builder.MakeCompound(newFaces); @@ -231,6 +241,7 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void) Direction.getValue(), getValidXDir()); builder.Add(newFaces,pFace); + } sectionFaces = newFaces; } @@ -240,6 +251,13 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void) std::string(e1->GetMessageString())); } + std::string symbol = dvp->SymbolSection.getValue(); + std::string symbolText = "Section " + symbol + "-" + symbol; + if (symbolText.compare(Label.getValue())) { + Label.setValue(symbolText.c_str()); + } + + touch(); return DrawView::execute(); } @@ -267,6 +285,7 @@ TopoDS_Compound DrawViewSection::findSectionPlaneIntersections(const TopoDS_Shap TopExp_Explorer expFaces(shape, TopAbs_FACE); int i; + int dbAdded = 0; for (i = 1 ; expFaces.More(); expFaces.Next(), i++) { const TopoDS_Face& face = TopoDS::Face(expFaces.Current()); BRepAdaptor_Surface adapt(face); @@ -275,6 +294,7 @@ TopoDS_Compound DrawViewSection::findSectionPlaneIntersections(const TopoDS_Shap if(plnSection.Contains(plnFace.Location(), Precision::Confusion()) && plnFace.Axis().IsParallel(plnSection.Axis(), Precision::Angular())) { + dbAdded++; builder.Add(result, face); } } @@ -334,27 +354,46 @@ TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face, HLRBRep_HLRToShape hlrToShape(brep_hlr); TopoDS_Shape hardEdges = hlrToShape.VCompound(); - TopoDS_Shape outEdges = hlrToShape.OutLineVCompound(); +// TopoDS_Shape outEdges = hlrToShape.OutLineVCompound(); std::vector faceEdges; TopExp_Explorer expl(hardEdges, TopAbs_EDGE); int i; for (i = 1 ; expl.More(); expl.Next(),i++) { - TopoDS_Edge edge = TopoDS::Edge(expl.Current()); + const TopoDS_Edge& edge = TopoDS::Edge(expl.Current()); if (edge.IsNull()) { Base::Console().Log("INFO - GO::projectFace - hard edge: %d is NULL\n",i); continue; } faceEdges.push_back(edge); } - expl.Init(outEdges, TopAbs_EDGE); - for (i = 1 ; expl.More(); expl.Next(),i++) { - TopoDS_Edge edge = TopoDS::Edge(expl.Current()); - if (edge.IsNull()) { - Base::Console().Log("INFO - GO::projectFace - outline edge: %d is NULL\n",i); - continue; - } - faceEdges.push_back(edge); - } + //if edge is both hard & outline, it will be duplicated? are hard edges enough? +// TopExp_Explorer expl2(outEdges, TopAbs_EDGE); +// for (i = 1 ; expl2.More(); expl2.Next(),i++) { +// const TopoDS_Edge& edge = TopoDS::Edge(expl2.Current()); +// if (edge.IsNull()) { +// Base::Console().Log("INFO - GO::projectFace - outline edge: %d is NULL\n",i); +// continue; +// } +// bool addEdge = true; +// //is edge already in faceEdges? maybe need to use explorer for this for IsSame to work? +// for (auto& e:faceEdges) { +// if (e.IsPartner(edge)) { +// addEdge = false; +// Base::Console().Message("TRACE - DVS::projectFace - skipping an edge 1\n"); +// } +// } +// expl.ReInit(); +// for (; expl.More(); expl.Next()){ +// const TopoDS_Edge& eHard = TopoDS::Edge(expl.Current()); +// if (eHard.IsPartner(edge)) { +// addEdge = false; +// Base::Console().Message("TRACE - DVS::projectFace - skipping an edge 2\n"); +// } +// } +// if (addEdge) { +// faceEdges.push_back(edge); +// } +// } std::vector uniqueVert = makeUniqueVList(faceEdges); std::vector walkerEdges = makeWalkerEdges(faceEdges,uniqueVert); @@ -363,29 +402,31 @@ TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face, ew.setSize(uniqueVert.size()); ew.loadEdges(walkerEdges); ew.perform(); - facelist result = ew.getResult(); //probably two Faces most of the time. Outerwire + real wires + facelist result = ew.getResult(); + result = TechDraw::EdgeWalker::removeDuplicateFaces(result); facelist::iterator iFace = result.begin(); std::vector fw; - for (;iFace != result.end(); iFace++) { + int dbi = 0; + for (;iFace != result.end(); iFace++,dbi++) { edgelist::iterator iEdge = (*iFace).begin(); std::vector fe; for (;iEdge != (*iFace).end(); iEdge++) { fe.push_back(faceEdges.at((*iEdge).idx)); } - TopoDS_Wire w = makeCleanWire(fe); //make 1 clean wire from its edges - fw.push_back(w); + TopoDS_Wire w = makeCleanWire(fe); + fw.push_back(w); } + TopoDS_Face projectedFace; if (!fw.empty()) { std::vector sortedWires = sortWiresBySize(fw); if (sortedWires.empty()) { return projectedFace; } - - //TODO: this really should have the same size checking logic as DVP - //remove the largest wire (OuterWire of graph) - sortedWires.erase(sortedWires.begin()); + //TODO: should have the same size checking logic as DVP? + //remove the largest wire (OuterWire of graph) ??? but duplicates have been removed? only do this if a mosaic? + //sortedWires.erase(sortedWires.begin()); BRepBuilderAPI_MakeFace mkFace(sortedWires.front(),true); //true => only want planes? std::vector::iterator itWire = ++sortedWires.begin(); //starting with second face diff --git a/src/Mod/TechDraw/App/DrawViewSection.h b/src/Mod/TechDraw/App/DrawViewSection.h index 2cacfc57d..b683a3690 100644 --- a/src/Mod/TechDraw/App/DrawViewSection.h +++ b/src/Mod/TechDraw/App/DrawViewSection.h @@ -1,6 +1,7 @@ /*************************************************************************** * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2007 * * Copyright (c) Luke Parry (l.parry@warwick.ac.uk) 2013 * + * 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 * @@ -54,6 +55,7 @@ public: DrawViewSection(void); virtual ~DrawViewSection(); + App::PropertyLink BaseView; App::PropertyVector SectionNormal; App::PropertyVector SectionOrigin; App::PropertyBool ShowCutSurface; diff --git a/src/Mod/TechDraw/Gui/CMakeLists.txt b/src/Mod/TechDraw/Gui/CMakeLists.txt index aa38389d4..902046b05 100644 --- a/src/Mod/TechDraw/Gui/CMakeLists.txt +++ b/src/Mod/TechDraw/Gui/CMakeLists.txt @@ -36,6 +36,7 @@ set(TechDrawGui_MOC_HDRS DlgPrefsTechDrawImp.h TaskLinkDim.h DlgTemplateField.h + TaskSectionView.h ) fc_wrap_cpp(TechDrawGui_MOC_SRCS ${TechDrawGui_MOC_HDRS}) @@ -48,6 +49,7 @@ set(TechDrawGui_UIC_SRCS TaskProjGroup.ui TaskLinkDim.ui DlgTemplateField.ui + TaskSectionView.ui ) qt4_wrap_ui(TechDrawGui_UIC_HDRS ${TechDrawGui_UIC_SRCS}) @@ -76,6 +78,9 @@ SET(TechDrawGui_SRCS DlgTemplateField.ui DlgTemplateField.cpp DlgTemplateField.h + TaskSectionView.ui + TaskSectionView.cpp + TaskSectionView.h ) SET(TechDrawGuiView_SRCS MDIViewPage.cpp @@ -134,6 +139,10 @@ SET(TechDrawGuiView_SRCS QGICMark.h QGIDimLines.cpp QGIDimLines.h + QGISectionLine.cpp + QGISectionLine.h + QGIDecoration.cpp + QGIDecoration.h TemplateTextField.cpp TemplateTextField.h ZVALUE.h @@ -174,6 +183,7 @@ SOURCE_GROUP("ViewProvider" FILES ${TechDrawGuiViewProvider_SRCS}) SET(TechDrawGuiTaskDlgs_SRCS TaskProjGroup.ui TaskLinkDim.ui + TaskSectionView.ui ) SOURCE_GROUP("TaskDialogs" FILES ${TechDrawGuiTaskDlgs_SRCS}) diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp index 5b2e6fb64..29fee1c6d 100644 --- a/src/Mod/TechDraw/Gui/Command.cpp +++ b/src/Mod/TechDraw/Gui/Command.cpp @@ -66,6 +66,7 @@ #include "MDIViewPage.h" #include "TaskProjGroup.h" +#include "TaskSectionView.h" #include "ViewProviderPage.h" using namespace TechDrawGui; @@ -362,27 +363,42 @@ CmdTechDrawNewViewSection::CmdTechDrawNewViewSection() void CmdTechDrawNewViewSection::activated(int iMsg) { + //TODO: should just use BaseView's page TechDraw::DrawPage* page = _findPage(this); if (!page) { return; } - std::vector shapes = getSelection().getObjectsOfType(Part::Feature::getClassTypeId()); + //std::vector shapes = getSelection().getObjectsOfType(Part::Feature::getClassTypeId()); + std::vector shapes = getSelection().getObjectsOfType(TechDraw::DrawViewPart::getClassTypeId()); if (shapes.empty()) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select at least 1 Part object.")); + QObject::tr("Select at least 1 DrawingView object.")); return; } + App::DocumentObject* dObj = *(shapes.begin()); + TechDraw::DrawViewPart* dvp = dynamic_cast(dObj); + if (dvp->getSectionRef()) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("This View already has a related Section. Choose another.")); + return; + } + std::string PageName = page->getNameInDocument(); Gui::WaitCursor wc; openCommand("Create view"); - for (std::vector::iterator it = shapes.begin(); it != shapes.end(); ++it) { - std::string FeatName = getUniqueObjectName("Section"); - doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewSection','%s')",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Source = App.activeDocument().%s",FeatName.c_str(),(*it)->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str()); - } + + std::string FeatName = getUniqueObjectName("Section"); + std::string SourceName = dvp->Source.getValue()->getNameInDocument(); + doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewSection','%s')",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Source = App.activeDocument().%s",FeatName.c_str(),SourceName.c_str()); + doCommand(Doc,"App.activeDocument().%s.BaseView = App.activeDocument().%s",FeatName.c_str(),(dObj)->getNameInDocument()); + doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str()); + App::DocumentObject *docObj = getDocument()->getObject(FeatName.c_str()); + TechDraw::DrawViewSection* dsv = dynamic_cast(docObj); + Gui::Control().showDialog(new TaskDlgSectionView(dvp,dsv)); + updateActive(); commitCommand(); } diff --git a/src/Mod/TechDraw/Gui/QGCustomText.cpp b/src/Mod/TechDraw/Gui/QGCustomText.cpp index d4861f60d..a31c31584 100644 --- a/src/Mod/TechDraw/Gui/QGCustomText.cpp +++ b/src/Mod/TechDraw/Gui/QGCustomText.cpp @@ -130,6 +130,7 @@ void QGCustomText::paint ( QPainter * painter, const QStyleOptionGraphicsItem * // scale values are same for same font size + different fonts. //double svgScale = 2.835; //72dpi/(25.4mm/in) //double svgScale = 3.84; //96dpi/(25mm/in) + //double svgScale = 3.6; //90dpi/(25mm/in) more/less CSS standard? double svgScale = 2.88; //72dpi/(25mm/in) Qt logicalDpiY() is int double svgMagicX = 8.0; //double svgMagicY = 7.5; //idk diff --git a/src/Mod/TechDraw/Gui/QGIDecoration.cpp b/src/Mod/TechDraw/Gui/QGIDecoration.cpp new file mode 100644 index 000000000..5f859f710 --- /dev/null +++ b/src/Mod/TechDraw/Gui/QGIDecoration.cpp @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (c) 2016 WandererFan * + * * + * 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 +#endif + +#include +#include +#include +#include + +#include +#include "QGIDecoration.h" + +using namespace TechDrawGui; + +QGIDecoration::QGIDecoration() : + m_colCurrent(Qt::black), + m_styleCurrent(Qt::SolidLine), + m_brushCurrent(Qt::SolidPattern) +{ + setCacheMode(QGraphicsItem::NoCache); + setAcceptHoverEvents(false); + setFlag(QGraphicsItem::ItemIsSelectable, false); + setFlag(QGraphicsItem::ItemIsMovable, false); + setFlag(QGraphicsItem::ItemSendsGeometryChanges,true); + + setWidth(1.0); +} + +void QGIDecoration::draw() +{ +} + +void QGIDecoration::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) { + QStyleOptionGraphicsItem myOption(*option); + myOption.state &= ~QStyle::State_Selected; + + QGraphicsItemGroup::paint (painter, &myOption, widget); +} + +void QGIDecoration::setWidth(double w) +{ + m_width = w; + m_pen.setWidthF(m_width); +} + +void QGIDecoration::setStyle(Qt::PenStyle s) +{ + m_styleCurrent = s; + m_pen.setStyle(m_styleCurrent); +} + +void QGIDecoration::setColor(QColor c) +{ + m_colCurrent = c; + m_pen.setColor(m_colCurrent); +} diff --git a/src/Mod/TechDraw/Gui/QGIDecoration.h b/src/Mod/TechDraw/Gui/QGIDecoration.h new file mode 100644 index 000000000..1800539a1 --- /dev/null +++ b/src/Mod/TechDraw/Gui/QGIDecoration.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (c) 2016 WandererFan * + * * + * 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 * + * * + ***************************************************************************/ + +#ifndef DRAWINGGUI_QGIDECORATION_H +#define DRAWINGGUI_QGIDECORATION_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QPainter; +class QStyleOptionGraphicsItem; +QT_END_NAMESPACE + +#include +#include + +namespace TechDrawGui +{ + +class TechDrawGuiExport QGIDecoration : public QGraphicsItemGroup +{ +public: + explicit QGIDecoration(void); + ~QGIDecoration() {} + enum {Type = QGraphicsItem::UserType + 173}; + int type() const { return Type;} + + virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ); + virtual void draw(); + void setWidth(double w); + void setStyle(Qt::PenStyle s); + void setColor(QColor c); + +protected: + QPen m_pen; + QBrush m_brush; + QColor m_colCurrent; + double m_width; + Qt::PenStyle m_styleCurrent; + Qt::BrushStyle m_brushCurrent; + +private: +}; + +} +#endif diff --git a/src/Mod/TechDraw/Gui/QGIFace.cpp b/src/Mod/TechDraw/Gui/QGIFace.cpp index 3722bb6d7..132156faa 100644 --- a/src/Mod/TechDraw/Gui/QGIFace.cpp +++ b/src/Mod/TechDraw/Gui/QGIFace.cpp @@ -61,7 +61,8 @@ QGIFace::QGIFace(int index) : setFlag(QGraphicsItem::ItemClipsChildrenToShape,true); //setFiltersChildEvents(true); - m_styleCurrent = Qt::NoPen; //don't draw face lines, just fill + //setStyle(Qt::NoPen); //don't draw face lines, just fill + setStyle(Qt::DashLine); m_styleNormal = m_styleDef; m_colNormalFill = m_colDefFill; diff --git a/src/Mod/TechDraw/Gui/QGISectionLine.cpp b/src/Mod/TechDraw/Gui/QGISectionLine.cpp new file mode 100644 index 000000000..85e3bf168 --- /dev/null +++ b/src/Mod/TechDraw/Gui/QGISectionLine.cpp @@ -0,0 +1,215 @@ +/*************************************************************************** + * Copyright (c) 2016 WandererFan * + * * + * 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 +#endif + +#include +#include +#include +#include + +#include +#include "QGIView.h" +#include "QGISectionLine.h" + +using namespace TechDrawGui; + +QGISectionLine::QGISectionLine() +{ + m_extLen = 8.0; + + m_line = new QGraphicsPathItem(); + addToGroup(m_line); + m_arrow1 = new QGIArrow(); + addToGroup(m_arrow1); + m_arrow2 = new QGIArrow(); + addToGroup(m_arrow2); + m_symbol1 = new QGCustomText(); + addToGroup(m_symbol1); + m_symbol2 = new QGCustomText(); + addToGroup(m_symbol2); + + setWidth(0.75); + setStyle(getSectionStyle()); + setColor(getSectionColor()); + +} + +void QGISectionLine::draw() +{ + prepareGeometryChange(); + makeLine(); + makeArrows(); + makeSymbols(); + update(); +} + +void QGISectionLine::makeLine() +{ + QPainterPath pp; + QPointF extLineStart,extLineEnd; + QPointF offset(m_arrowDir.x,-m_arrowDir.y); + offset = 0.80 * m_extLen * offset; //0.80 is hack to hide line end behind arrowhead + extLineStart = m_start + offset; + extLineEnd = m_end + offset; + pp.moveTo(extLineStart); + pp.lineTo(m_start); + pp.lineTo(m_end); + pp.lineTo(extLineEnd); + m_line->setPath(pp); +} + +void QGISectionLine::makeArrows() +{ + double arrowRotation = 0.0; +// m_arrowDir.normalize(); +// double angle = atan2f(m_arrowDir.y,m_arrowDir.x); +// if (angle < 0.0) { +// angle = 2 * M_PI + angle; +// } + + Base::Vector3d up(0,1,0); + Base::Vector3d down(0,-1,0); + Base::Vector3d right(1,0,0); + Base::Vector3d left(-1,0,0); + if (m_arrowDir == up) { + arrowRotation = 270.0; + } else if (m_arrowDir == down) { + arrowRotation = 90.0; + } else if (m_arrowDir == right) { + arrowRotation = 0.0; + } else if (m_arrowDir == left) { + arrowRotation = 180.0; + } else { + Base::Console().Message("Please make feature request for oblique section lines\n"); + } + + QPointF extLineStart,extLineEnd; + QPointF offset(m_arrowDir.x,-m_arrowDir.y); //remember Y dir is flipped + offset = m_extLen * offset; + extLineStart = m_start + offset; + extLineEnd = m_end + offset; + + m_arrow1->setPos(extLineStart); + //m_arrow1->flip(true); + m_arrow1->draw(); + m_arrow1->setRotation(arrowRotation); + m_arrow2->setPos(extLineEnd); + m_arrow2->draw(); + m_arrow2->setRotation(arrowRotation); +} + +void QGISectionLine::makeSymbols() +{ + QPointF extLineStart,extLineEnd; + QPointF offset(m_arrowDir.x,-m_arrowDir.y); + offset = 2.0 * m_extLen * offset; + extLineStart = m_start + offset; + extLineEnd = m_end + offset; + + prepareGeometryChange(); + m_symFont.setPointSize(m_symSize); + m_symbol1->setFont(m_symFont); + m_symbol1->setPlainText(QString::fromUtf8(m_symbol)); + m_symbol1->centerAt(extLineStart); + m_symbol2->setFont(m_symFont); + m_symbol2->setPlainText(QString::fromUtf8(m_symbol)); + m_symbol2->centerAt(extLineEnd); +} + + +void QGISectionLine::setBounds(double x1,double y1,double x2,double y2) +{ + m_start = QPointF(x1,y1); + m_end = QPointF(x2,y2); +} + +void QGISectionLine::setSymbol(char* sym) +{ + m_symbol = sym; +} + +void QGISectionLine::setDirection(double xDir,double yDir) +{ + Base::Vector3d newDir(xDir,yDir,0.0); + setDirection(newDir); +} + +void QGISectionLine::setDirection(Base::Vector3d dir) +{ + m_arrowDir = dir; +} + +void QGISectionLine::setFont(QFont f, double fsize) +{ + m_symFont = f; + m_symSize = fsize; +} + + +QColor QGISectionLine::getSectionColor() +{ + Base::Reference hGrp = App::GetApplication().GetUserParameter() + .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Colors"); + App::Color fcColor = App::Color((uint32_t) hGrp->GetUnsigned("SectionColor", 0x08080800)); + return fcColor.asValue(); +} + +Qt::PenStyle QGISectionLine::getSectionStyle() +{ + Base::Reference hGrp = App::GetApplication().GetUserParameter().GetGroup("BaseApp")-> + GetGroup("Preferences")->GetGroup("Mod/TechDraw"); + Qt::PenStyle sectStyle = static_cast (hGrp->GetInt("SectionLine",2)); + return sectStyle; +} + +void QGISectionLine::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) { + QStyleOptionGraphicsItem myOption(*option); + myOption.state &= ~QStyle::State_Selected; + + setTools(); + QGIDecoration::paint (painter, &myOption, widget); +} + +void QGISectionLine::setTools() +{ + m_pen.setWidthF(m_width); + m_pen.setColor(m_colCurrent); + m_pen.setStyle(m_styleCurrent); + m_brush.setStyle(m_brushCurrent); + m_brush.setColor(m_colCurrent); + + m_line->setPen(m_pen); + + m_arrow1->setPen(m_pen); + m_arrow2->setPen(m_pen); + m_arrow1->setBrush(m_brush); + m_arrow2->setBrush(m_brush); + + m_symbol1->setDefaultTextColor(m_colCurrent); + m_symbol2->setDefaultTextColor(m_colCurrent); +} diff --git a/src/Mod/TechDraw/Gui/QGISectionLine.h b/src/Mod/TechDraw/Gui/QGISectionLine.h new file mode 100644 index 000000000..20f225ef0 --- /dev/null +++ b/src/Mod/TechDraw/Gui/QGISectionLine.h @@ -0,0 +1,87 @@ +/*************************************************************************** + * Copyright (c) 2016 WandererFan * + * * + * 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 * + * * + ***************************************************************************/ + +#ifndef TECHDRAWGUI_QGISECTIONLINE_H +#define TECHDRAWGUI_QGISECTIONLINE_H + +#include +#include +#include +#include +#include + +#include + +#include "QGIArrow.h" +#include "QGCustomText.h" +#include "QGIDecoration.h" + +namespace TechDrawGui +{ + +class TechDrawGuiExport QGISectionLine : public QGIDecoration +{ +public: + explicit QGISectionLine(); + ~QGISectionLine() {} + + enum {Type = QGraphicsItem::UserType + 172}; + int type() const { return Type;} + + virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ); + + void setBounds(double x1,double y1,double x2,double y2); + void setSymbol(char* sym); + void setDirection(double xDir,double yDir); + void setDirection(Base::Vector3d dir); + void setFont(QFont f, double fsize); + virtual void draw(); + +protected: + QColor getSectionColor(); + Qt::PenStyle getSectionStyle(); + void makeLine(); + void makeArrows(); + void makeSymbols(); + void setTools(); + +private: + char* m_symbol; + QGraphicsPathItem* m_line; //primpath? + QGIArrow* m_arrow1; + QGIArrow* m_arrow2; + QGCustomText* m_symbol1; + QGCustomText* m_symbol2; + QPointF m_start; + QPointF m_end; + Base::Vector3d m_arrowDir; + std::string m_symFontName; + QFont m_symFont; + double m_symSize; + double m_arrowSize; + //QColor m_color; + double m_extLen; +}; + +} + +#endif // TECHDRAWGUI_QGISECTIONLINE_H diff --git a/src/Mod/TechDraw/Gui/QGIUserTypes.h b/src/Mod/TechDraw/Gui/QGIUserTypes.h new file mode 100644 index 000000000..b5ef6a818 --- /dev/null +++ b/src/Mod/TechDraw/Gui/QGIUserTypes.h @@ -0,0 +1,49 @@ +/* +Derived QGraphicsItem Classes type() Values + +Qt First UserType = 65536 + +QGraphicsItemView : 101 +QGraphicsItemViewPart : 102 +QGraphicsItemEdge: 103 +QGraphicsItemFace: 104 +QGraphicsItemVertex: 105 +QGraphicsItemViewDimension : 106 +QGraphicsItemDatumLabel : 107 +QGraphicsItemViewSection : 108 +QGraphicsItemArrow: 109 +QGraphicsItemViewCollection : 110 +QGraphicsItemViewOrthographic : 113 +QGraphicsItemViewAnnotation : 120 +QGraphicsItemViewSymbol : 121 +QGraphicsItemHatch : 122 //obsolete +QGraphicsItemClip : 123 +QGraphicsItemSpreadsheet : 124 +QGCustomText: 130 +QGCustomSvg: 131 +QGCustomClip: 132 +QGCustomRect: 133 +QGCustomLabel:135 +QGCustomBorder: 136 +QGraphicsItemTemplate: 150 +QGraphicsItemDrawingTemplate: 151 +QGraphicsItemSVGTemplate: 153 +TemplateTextField: 160 +QGIPrimPath: 170 +QGICMark: 171 +QGISectionLine: 172 +QGIDecoration: 173 +*/ + +/* +Standard Types +path 2 +rect 3 +ellipse 4 +polygon 5 +line 6 +pixmap 7 +text 8 +simpletext 9 +group 10 +*/ diff --git a/src/Mod/TechDraw/Gui/QGIView.cpp b/src/Mod/TechDraw/Gui/QGIView.cpp index 6e891258d..2a23e24fe 100644 --- a/src/Mod/TechDraw/Gui/QGIView.cpp +++ b/src/Mod/TechDraw/Gui/QGIView.cpp @@ -359,7 +359,7 @@ void QGIView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q QRectF QGIView::customChildrenBoundingRect() { QList children = childItems(); - int dimItemType = QGraphicsItem::UserType + 106; // TODO: Magic number warning. make include file for custom types? + int dimItemType = QGraphicsItem::UserType + 106; // TODO: Magic number warning. int borderItemType = QGraphicsItem::UserType + 136; // TODO: Magic number warning int labelItemType = QGraphicsItem::UserType + 135; // TODO: Magic number warning QRectF result; diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.cpp b/src/Mod/TechDraw/Gui/QGIViewPart.cpp index 7bf5d4531..317834427 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewPart.cpp @@ -46,9 +46,11 @@ #include #include #include +#include #include #include +#include #include #include "ZVALUE.h" @@ -56,6 +58,9 @@ #include "QGIEdge.h" #include "QGIVertex.h" #include "QGICMark.h" +#include "QGISectionLine.h" +#include "QGCustomBorder.h" +#include "QGCustomLabel.h" #include "QGIViewPart.h" using namespace TechDrawGui; @@ -73,6 +78,8 @@ QGIViewPart::QGIViewPart() setFlag(QGraphicsItem::ItemIsMovable, true); setFlag(QGraphicsItem::ItemSendsScenePositionChanges, true); setFlag(QGraphicsItem::ItemSendsGeometryChanges,true); + + showSection = false; } QGIViewPart::~QGIViewPart() @@ -285,6 +292,7 @@ void QGIViewPart::drawViewPart() prepareGeometryChange(); removePrimitives(); //clean the slate + removeDecorations(); #if MOD_TECHDRAW_HANDLE_FACES // Draw Faces @@ -367,7 +375,12 @@ void QGIViewPart::drawViewPart() item->setRadius(lineWidth * vertexScaleFactor); item->setZValue(ZVALUE::VERTEX); } - } + } + //draw section line + if (viewPart->ShowSectionLine.getValue() && + viewPart->getSectionRef() ) { + drawSectionLine(true); + } } QGIFace* QGIViewPart::drawFace(TechDrawGeometry::Face* f, int idx) @@ -385,10 +398,12 @@ QGIFace* QGIViewPart::drawFace(TechDrawGeometry::Face* f, int idx) edgePath = edgePath.toReversed(); } wirePath.connectPath(edgePath); - wirePath.setFillRule(Qt::WindingFill); } + //dumpPath("wirePath:",wirePath); facePath.addPath(wirePath); } + facePath.setFillRule(Qt::OddEvenFill); + QGIFace* gFace = new QGIFace(idx); addToGroup(gFace); gFace->setPos(0.0,0.0); @@ -416,6 +431,81 @@ void QGIViewPart::removePrimitives() } } +//! Remove all existing QGIDecoration items(SectionLine,SectionMark,...) +void QGIViewPart::removeDecorations() +{ + QList children = childItems(); + for (auto& c:children) { + QGIDecoration* decor = dynamic_cast(c); + if (decor) { + removeFromGroup(decor); + scene()->removeItem(decor); + delete decor; + } + } +} + +void QGIViewPart::drawSectionLine(bool b) +{ + TechDraw::DrawViewPart *viewPart = dynamic_cast(getViewObject()); + TechDraw::DrawViewSection *viewSection = viewPart->getSectionRef(); + if (!viewPart || + !viewSection) { + return; + } + if (b) { + QGISectionLine* sectionLine = new QGISectionLine(); + addToGroup(sectionLine); + sectionLine->setSymbol(const_cast(viewPart->SymbolSection.getValue())); + Base::Vector3d sectionDir(0,1,0); + Base::Vector3d up(0,1,0); + Base::Vector3d down(0,-1,0); + Base::Vector3d right(1,0,0); + Base::Vector3d left(-1,0,0); + bool horiz = viewPart->HorizSectionLine.getValue(); + bool normal = viewPart->ArrowUpSection.getValue(); + if (horiz && normal) { + sectionDir = up; + } else if (horiz && !normal) { + sectionDir = down; + } else if (!horiz && normal) { + sectionDir = right; + } else if (!horiz && !normal) { + sectionDir = left; + } + sectionLine->setDirection(sectionDir.x,sectionDir.y); + + Base::Vector3d org = viewSection->SectionOrigin.getValue(); + double scale = viewPart->Scale.getValue(); + Base::Vector3d pOrg = scale * viewPart->projectPoint(org); + pOrg.y = -1 * pOrg.y; + //now project pOrg onto sectionDir + Base::Vector3d displace; + displace.ProjectToLine(pOrg, sectionDir); + Base::Vector3d offset = pOrg + displace; + + sectionLine->setPos(offset.x,offset.y); + double sectionSpan; + double sectionFudge = 10.0; + double xVal, yVal; + if (horiz) { + sectionSpan = m_border->rect().width() + sectionFudge; + xVal = sectionSpan / 2.0; + yVal = 0.0; + } else { + sectionSpan = (m_border->rect().height() - m_label->boundingRect().height()) + sectionFudge; + xVal = 0.0; + yVal = sectionSpan / 2.0; + } + sectionLine->setBounds(-xVal,-yVal,xVal,yVal); + sectionLine->setWidth(viewPart->LineWidth.getValue()); //TODO: add fudge to make sectionLine thinner than reg lines? + sectionLine->setFont(m_font,6.0); + sectionLine->setZValue(ZVALUE::SECTIONLINE); + sectionLine->draw(); + } +} + + // As called by arc of ellipse case: // pathArc(path, geom->major, geom->minor, geom->angle, geom->largeArc, geom->cw, // geom->endPnt.fX, geom->endPnt.fY, diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.h b/src/Mod/TechDraw/Gui/QGIViewPart.h index 221a5f960..d4bdadff7 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.h +++ b/src/Mod/TechDraw/Gui/QGIViewPart.h @@ -57,6 +57,8 @@ public: virtual void updateView(bool update = false) override; void tidy(); virtual QRectF boundingRect() const override; + virtual void drawSectionLine(bool b); + bool showSection; virtual void draw() override; @@ -86,6 +88,7 @@ protected: TechDraw::DrawHatch* faceIsHatched(int i,std::vector hatchObjs) const; void dumpPath(const char* text,QPainterPath path); void removePrimitives(void); + void removeDecorations(void); private: QList deleteItems; diff --git a/src/Mod/TechDraw/Gui/QGIViewSection.cpp b/src/Mod/TechDraw/Gui/QGIViewSection.cpp index 1470c6d08..5a5469896 100644 --- a/src/Mod/TechDraw/Gui/QGIViewSection.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewSection.cpp @@ -101,3 +101,8 @@ void QGIViewSection::updateView(bool update) QGIViewPart::updateView(); } } + +void QGIViewSection::drawSectionLine(bool b) +{ + //override QGIVP::drawSectionLine +} diff --git a/src/Mod/TechDraw/Gui/QGIViewSection.h b/src/Mod/TechDraw/Gui/QGIViewSection.h index 54da22755..2368f7900 100644 --- a/src/Mod/TechDraw/Gui/QGIViewSection.h +++ b/src/Mod/TechDraw/Gui/QGIViewSection.h @@ -39,6 +39,8 @@ public: void updateView(bool update = false) override; enum {Type = QGraphicsItem::UserType + 108}; int type() const override { return Type;} + void drawSectionLine(bool b) override; + protected: void drawSectionFace(); diff --git a/src/Mod/TechDraw/Gui/TaskSectionView.cpp b/src/Mod/TechDraw/Gui/TaskSectionView.cpp new file mode 100644 index 000000000..eb2915f17 --- /dev/null +++ b/src/Mod/TechDraw/Gui/TaskSectionView.cpp @@ -0,0 +1,324 @@ +/*************************************************************************** + * Copyright (c) 2016 WandererFan * + * * + * 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 +#endif // #ifndef _PreComp_ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include "TaskSectionView.h" +#include + +using namespace Gui; +using namespace TechDrawGui; + + +TaskSectionView::TaskSectionView(TechDraw::DrawViewPart* base, TechDraw::DrawViewSection* section) : + ui(new Ui_TaskSectionView), + m_base(base), + m_section(section) +{ + ui->setupUi(this); + + connect(ui->cbHoriz, SIGNAL(clicked(bool)), + this, SLOT(onHorizontalClicked(bool))); + connect(ui->cbVert, SIGNAL(clicked(bool)), + this, SLOT(onVerticalClicked(bool))); + connect(ui->cbNormal, SIGNAL(clicked(bool)), + this, SLOT(onNormalClicked(bool))); + connect(ui->cbReverse, SIGNAL(clicked(bool)), + this, SLOT(onReverseClicked(bool))); + connect(ui->pbCalc, SIGNAL(clicked(bool)), + this, SLOT(onCalcClicked(bool))); + connect(ui->pbReset, SIGNAL(clicked(bool)), + this, SLOT(onResetClicked(bool))); + + saveInitialValues(); + resetValues(); +} + +TaskSectionView::~TaskSectionView() +{ + delete ui; +} + + +void TaskSectionView::saveInitialValues() +{ + saveSym = m_base->SymbolSection.getValue(); + saveHorizSectionLine = m_base->HorizSectionLine.getValue(); //true(horiz)/false(vert) + saveArrowUpSection = m_base->ArrowUpSection.getValue(); //true(up/right)/false(down/left) + saveSectionOrigin = m_section->SectionOrigin.getValue(); + saveSectionXDir = m_section->XAxisDirection.getValue(); + saveSectionDirection = m_section->Direction.getValue(); + saveSectionNormal = m_section->SectionNormal.getValue(); + saveLabel = m_section->Label.getValue(); +} + +void TaskSectionView::resetValues() +{ + ui->leSymbol->setText(QString::fromUtf8(saveSym.data(), saveSym.size())); + + ui->cbHoriz->setChecked(false); + ui->cbVert->setChecked(false); + ui->cbNormal->setChecked(false); + ui->cbReverse->setChecked(false); + if (saveHorizSectionLine && saveArrowUpSection) { + ui->cbHoriz->setChecked(true); + ui->cbNormal->setChecked(true); + } else if (saveHorizSectionLine && !saveArrowUpSection) { + ui->cbHoriz->setChecked(true); + ui->cbReverse->setChecked(true); + } else if (!saveHorizSectionLine && saveArrowUpSection) { + ui->cbVert->setChecked(true); + ui->cbNormal->setChecked(true); + } else if (!saveHorizSectionLine && !saveArrowUpSection) { + ui->cbVert->setChecked(true); + ui->cbReverse->setChecked(true); + } else { + Base::Console().Error("%s Symbol Line Direction is invalid\n", m_base->getNameInDocument()); + } + + ui->sbOrgX->setValue(saveSectionOrigin.x); + ui->sbOrgY->setValue(saveSectionOrigin.y); + ui->sbOrgZ->setValue(saveSectionOrigin.z); + + ui->sbXX->setValue(saveSectionXDir.x); + ui->sbXY->setValue(saveSectionXDir.y); + ui->sbXZ->setValue(saveSectionXDir.z); + + ui->leProjDir->setReadOnly(true); + ui->leProjDir->setText(formatVector(saveSectionDirection)); + ui->leNormal->setReadOnly(true); + ui->leNormal->setText(formatVector(saveSectionNormal)); + + m_section->Label.setValue(saveLabel.c_str()); +} + +void TaskSectionView::calcValues() +{ + if (ui->cbHoriz->isChecked() && + ui->cbNormal->isChecked()) { + sectionNormal = m_base->getVDir(); + } else if (ui->cbHoriz->isChecked() && + ui->cbReverse->isChecked()) { + sectionNormal = -1.0 * m_base->getVDir(); + } else if (ui->cbVert->isChecked() && + ui->cbNormal->isChecked()) { + sectionNormal = m_base->getUDir(); + } else if (ui->cbVert->isChecked() && + ui->cbReverse->isChecked() ) { + sectionNormal = -1.0 * m_base->getUDir(); + } else { + Base::Console().Error("%s Symbol Line Direction is invalid\n", m_base->getNameInDocument()); + } + + sectionProjDir = sectionNormal; //typical use-case is view perp to face + ui->leProjDir->setText(formatVector(sectionProjDir)); + ui->leNormal->setText(formatVector(sectionNormal)); + + Base::Vector3d xDirIn(ui->sbXX->value().getValue(), + ui->sbXY->value().getValue(), + ui->sbXZ->value().getValue()); + Base::Vector3d xDirValid = m_section->getValidXDir(); + if (xDirIn != xDirValid) { + ui->sbXX->setValue(xDirValid.x); + ui->sbXY->setValue(xDirValid.y); + ui->sbXZ->setValue(xDirValid.z); + } + //TODO: sectionOrigin check? already in DVS. +} + +void TaskSectionView::updateValues() +{ + m_section->Direction.setValue(sectionProjDir); + m_section->SectionNormal.setValue(sectionNormal); + Base::Vector3d origin(ui->sbOrgX->value().getValue(), + ui->sbOrgY->value().getValue(), + ui->sbOrgZ->value().getValue()); + m_section->SectionOrigin.setValue(origin); + Base::Vector3d xDir(ui->sbXX->value().getValue(), + ui->sbXY->value().getValue(), + ui->sbXZ->value().getValue()); + m_section->XAxisDirection.setValue(xDir); + m_base->SymbolSection.setValue(ui->leSymbol->text().toUtf8().constData()); + m_base->HorizSectionLine.setValue(ui->cbHoriz->isChecked()); + m_base->ArrowUpSection.setValue(ui->cbNormal->isChecked()); + + //TODO: this doesn't support restoration of saved Label. + std::string symbol = m_base->SymbolSection.getValue(); + std::string symbolText = "Section " + symbol + "-" + symbol; + if (symbolText.compare(m_section->Label.getValue())) { + m_section->Label.setValue(symbolText.c_str()); + } + + m_base->getDocument()->recompute(); +} + + +void TaskSectionView::onHorizontalClicked(bool b) +{ + ui->cbHoriz->blockSignals(true); + ui->cbVert->blockSignals(true); + ui->cbHoriz->setChecked(true); + ui->cbVert->setChecked(false); + ui->cbHoriz->blockSignals(false); + ui->cbVert->blockSignals(false); +} + +void TaskSectionView::onVerticalClicked(bool b) +{ + ui->cbHoriz->blockSignals(true); + ui->cbVert->blockSignals(true); + ui->cbVert->setChecked(true); + ui->cbHoriz->setChecked(false); + ui->cbHoriz->blockSignals(false); + ui->cbVert->blockSignals(false); +} + +void TaskSectionView::onNormalClicked(bool b) +{ + ui->cbNormal->blockSignals(true); + ui->cbReverse->blockSignals(true); + ui->cbNormal->setChecked(true); + ui->cbReverse->setChecked(false); + ui->cbNormal->blockSignals(false); + ui->cbReverse->blockSignals(false); +} + +void TaskSectionView::onReverseClicked(bool b) +{ + ui->cbReverse->blockSignals(true); + ui->cbNormal->blockSignals(true); + ui->cbReverse->setChecked(true); + ui->cbNormal->setChecked(false); + ui->cbReverse->blockSignals(false); + ui->cbNormal->blockSignals(false); +} + + +void TaskSectionView::onCalcClicked(bool b) +{ + calcValues(); + updateValues(); +} + +void TaskSectionView::onResetClicked(bool b) +{ + resetValues(); + updateValues(); + m_section->Label.setValue(saveLabel.c_str()); +} + + +bool TaskSectionView::accept() +{ + calcValues(); + updateValues(); + return true; +} + +bool TaskSectionView::reject() +{ + resetValues(); + updateValues(); + m_section->Label.setValue(saveLabel.c_str()); + return true; +} + +void TaskSectionView::changeEvent(QEvent *e) +{ + if (e->type() == QEvent::LanguageChange) { + ui->retranslateUi(this); + } +} + +QString TaskSectionView::formatVector(Base::Vector3d v) +{ + QString data = QString::fromLatin1("[%1 %2 %3]") + .arg(QLocale::system().toString(v.x, 'f', 2)) + .arg(QLocale::system().toString(v.y, 'f', 2)) + .arg(QLocale::system().toString(v.z, 'f', 2)); + return data; +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +TaskDlgSectionView::TaskDlgSectionView(TechDraw::DrawViewPart* base, TechDraw::DrawViewSection* section) : + TaskDialog() +{ + widget = new TaskSectionView(base,section); + taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("TechDraw_Tree_View"), + widget->windowTitle(), true, 0); + taskbox->groupLayout()->addWidget(widget); + Content.push_back(taskbox); +} + +TaskDlgSectionView::~TaskDlgSectionView() +{ +} + +void TaskDlgSectionView::update() +{ + //widget->updateTask(); +} + +//==== calls from the TaskView =============================================================== +void TaskDlgSectionView::open() +{ +} + +void TaskDlgSectionView::clicked(int i) +{ +} + +bool TaskDlgSectionView::accept() +{ + widget->accept(); + return true; +} + +bool TaskDlgSectionView::reject() +{ + widget->reject(); + return true; +} + +#include diff --git a/src/Mod/TechDraw/Gui/TaskSectionView.h b/src/Mod/TechDraw/Gui/TaskSectionView.h new file mode 100644 index 000000000..3d7d49fd4 --- /dev/null +++ b/src/Mod/TechDraw/Gui/TaskSectionView.h @@ -0,0 +1,122 @@ +/*************************************************************************** + * Copyright (c) 2016 WandererFan * + * * + * 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 * + * * + ***************************************************************************/ + +#ifndef GUI_TASKVIEW_TASKSECTIONVIEW_H +#define GUI_TASKVIEW_TASKSECTIONVIEW_H + +#include +#include + +#include + +#include +#include + + +class Ui_TaskSectionView; + +namespace TechDrawGui +{ + +class TaskSectionView : public QWidget +{ + Q_OBJECT + +public: + TaskSectionView(TechDraw::DrawViewPart* base, TechDraw::DrawViewSection* section); + ~TaskSectionView(); + +public: + bool accept(); + bool reject(); + +protected Q_SLOTS: + void onHorizontalClicked(bool b); + void onVerticalClicked(bool b); + void onNormalClicked(bool b); + void onReverseClicked(bool b); + void onCalcClicked(bool b); + void onResetClicked(bool b); + +protected: + void changeEvent(QEvent *e); + void resetValues(); + void calcValues(); + void saveInitialValues(); + void updateValues(); + QString formatVector(Base::Vector3d v); + +private: + Ui_TaskSectionView * ui; + TechDraw::DrawViewPart* m_base; + TechDraw::DrawViewSection* m_section; + Base::Vector3d sectionNormal; + Base::Vector3d sectionProjDir; + Base::Vector3d sectionOrigin; + Base::Vector3d sectionxDir; + + std::string saveSym; + std::string saveLabel; + bool saveHorizSectionLine; + bool saveArrowUpSection; + Base::Vector3d saveSectionDirection; + Base::Vector3d saveSectionXDir; + Base::Vector3d saveSectionOrigin; + Base::Vector3d saveSectionNormal; + + +}; + +class TaskDlgSectionView : public Gui::TaskView::TaskDialog +{ + Q_OBJECT + +public: + TaskDlgSectionView(TechDraw::DrawViewPart* base, TechDraw::DrawViewSection* section); + ~TaskDlgSectionView(); + +public: + /// is called the TaskView when the dialog is opened + virtual void open(); + /// is called by the framework if an button is clicked which has no accept or reject role + virtual void clicked(int); + /// is called by the framework if the dialog is accepted (Ok) + virtual bool accept(); + /// is called by the framework if the dialog is rejected (Cancel) + virtual bool reject(); + /// is called by the framework if the user presses the help button + virtual void helpRequested() { return;} + virtual bool isAllowedAlterDocument(void) const + { return false; } + + void update(); + +protected: + +private: + TaskSectionView * widget; + Gui::TaskView::TaskBox* taskbox; +}; + +} //namespace TechDrawGui + +#endif // #ifndef GUI_TASKVIEW_TASKSECTIONVIEW_H diff --git a/src/Mod/TechDraw/Gui/TaskSectionView.ui b/src/Mod/TechDraw/Gui/TaskSectionView.ui new file mode 100644 index 000000000..164134491 --- /dev/null +++ b/src/Mod/TechDraw/Gui/TaskSectionView.ui @@ -0,0 +1,303 @@ + + + TechDrawGui::TaskSectionView + + + + 0 + 0 + 358 + 461 + + + + + 0 + 0 + + + + + 250 + 0 + + + + Calculate Section Parameters + + + + + + + 0 + 0 + + + + Section Line Parameters + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Symbol + + + + + + + A + + + + + + + + + + + Arrows + + + + + + + Horizontal + + + + + + + Vertical + + + + + + + Line + + + + + + + Down/Left + + + + + + + Up/Right + + + + + + + + + + + + Qt::Horizontal + + + + + + + Section View Parameters + + + + + + + + X + + + + + + + + + + + + + + Y + + + + + + + + + + + + + + + + + + + + + + + + + + + + Section Origin + + + Qt::AlignCenter + + + + + + + X Axis + + + Qt::AlignCenter + + + + + + + Z + + + + + + + + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + + + + Calculated Values + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Projection Direction + + + + + + + true + + + + + + + Section Normal + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Calc + + + + + + + Reset + + + + + + + + + + + + + Gui::QuantitySpinBox + QWidget +
Gui/QuantitySpinBox.h
+
+
+ + +
diff --git a/src/Mod/TechDraw/Gui/ZVALUE.h b/src/Mod/TechDraw/Gui/ZVALUE.h index 75834212f..683e3810a 100644 --- a/src/Mod/TechDraw/Gui/ZVALUE.h +++ b/src/Mod/TechDraw/Gui/ZVALUE.h @@ -6,10 +6,11 @@ namespace ZVALUE { const int SVGTEMPLATE = -500; const int FACE = 10; const int SECTIONFACE = 20; - const int HATCH = 25; - const int HIDEDGE = 27; - const int EDGE = 30; - const int VERTEX = 40; - const int DIMENSION = 50; + const int HATCH = 30; + const int HIDEDGE = 40; + const int EDGE = 50; + const int VERTEX = 60; + const int DIMENSION = 70; + const int SECTIONLINE = 80; } #endif