From ca8adc3aab08394975e4310afc8155358670b839 Mon Sep 17 00:00:00 2001 From: WandererFan Date: Thu, 15 Dec 2016 09:01:45 -0500 Subject: [PATCH] getViewAxis -> DVP virtual method --- src/Mod/TechDraw/App/DrawProjGroupItem.cpp | 110 +- src/Mod/TechDraw/App/DrawProjGroupItem.h | 6 +- src/Mod/TechDraw/App/DrawProjectSplit.cpp | 21 +- src/Mod/TechDraw/App/DrawProjectSplit.h | 2 +- src/Mod/TechDraw/App/DrawViewDetail.cpp | 5 +- src/Mod/TechDraw/App/DrawViewMulti.cpp | 3 +- src/Mod/TechDraw/App/DrawViewPart.cpp | 34 +- src/Mod/TechDraw/App/DrawViewPart.h | 8 +- src/Mod/TechDraw/App/DrawViewSection.cpp | 7 +- src/Mod/TechDraw/App/GeometryObject.cpp | 1107 ++++++++++---------- src/Mod/TechDraw/App/GeometryObject.h | 256 ++--- 11 files changed, 861 insertions(+), 698 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp index 0d24934dc..79e46929b 100644 --- a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp +++ b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp @@ -26,9 +26,12 @@ # include #endif +#include #include #include +#include "GeometryObject.h" +#include "DrawUtil.h" #include "DrawProjGroup.h" #include "DrawProjGroupItem.h" @@ -56,28 +59,52 @@ DrawProjGroupItem::DrawProjGroupItem(void) { Type.setEnums(TypeEnums); ADD_PROPERTY(Type, ((long)0)); + ADD_PROPERTY_TYPE(OrientBasis ,(1.0,0.0,0.0) ,"Base",App::Prop_None,"Controls rotary orientation of item in view. "); //projection group controls these Direction.setStatus(App::Property::ReadOnly,true); + //OrientBasis.setStatus(App::Property::ReadOnly,true); Scale.setStatus(App::Property::ReadOnly,true); ScaleType.setStatus(App::Property::ReadOnly,true); } short DrawProjGroupItem::mustExecute() const { - if (Type.isTouched()) - return 1; + short result = 0; + if (!isRestoring()) { + result = (Direction.isTouched() || + OrientBasis.isTouched() || + Source.isTouched() || + Scale.isTouched() || + ScaleType.isTouched()); + } + + if (result) { + return result; + } return TechDraw::DrawViewPart::mustExecute(); } void DrawProjGroupItem::onChanged(const App::Property *prop) { - //TODO: Should we allow changes to the Type here? Seems that should be handled through DrawProjGroup - if (prop == &Type && Type.isTouched()) { - if (!isRestoring()) { - execute(); - } - } +// //TODO: too many executes! +// //TODO: Should we allow changes to the Type here? Seems that should be handled through DrawProjGroup +// if (!isRestoring()) { +//// //Base::Console().Message("TRACE - DPGI::onChanged(%s) - %s/%s\n",prop->getName(),getNameInDocument(),Label.getValue()); +// if (prop == &Type && Type.isTouched()) { +//// //Base::Console().Message("TRACE - DPGI::onChanged(%s) - Type: %s\n",prop->getName(),Type.getValueAsString()); +//// execute(); +// } else if (prop == &Direction) { +// if (getGroup() != nullptr) { +// OrientBasis.setValue(getGroup()->getXAxisDir(Type.getValueAsString())); +// Base::Console().Message("TRACE - DPGI::onChanged(%s) - Direction: %s Orient: %s\n", +// prop->getName(),DrawUtil::formatVector(Direction.getValue()).c_str(), +// DrawUtil::formatVector(OrientBasis.getValue()).c_str()); +// } +// } +//// execute(); +//// } //else if (prop == &OrientBasis) { //don't want to do twice though! +// } TechDraw::DrawViewPart::onChanged(prop); @@ -96,7 +123,7 @@ void DrawProjGroupItem::onDocumentRestored() } } -DrawProjGroup* DrawProjGroupItem::getGroup() +DrawProjGroup* DrawProjGroupItem::getGroup() const { DrawProjGroup* result = nullptr; std::vector parent = getInList(); @@ -108,6 +135,71 @@ DrawProjGroup* DrawProjGroupItem::getGroup() } return result; } +gp_Ax2 DrawProjGroupItem::getViewAxis(const Base::Vector3d& pt, + const Base::Vector3d& axis, + const bool flip) const +{ +// Base::Console().Message("TRACE - DPGI::getViewAxis - %s/%s - Type: %s\n",getNameInDocument(),Label.getValue(),Type.getValueAsString()); + gp_Ax2 viewAxis; + Base::Vector3d x = OrientBasis.getValue(); + Base::Vector3d nx = x; + x.Normalize(); + Base::Vector3d na = axis; + na.Normalize(); +// Base::Console().Message("TRACE - DPGI::getViewAxis - axis: %s orient: %s\n", +// DrawUtil::formatVector(axis).c_str(),DrawUtil::formatVector(x).c_str()); + + if (DrawUtil::checkParallel(nx,na)) { //parallel/antiparallel +// Base::Console().Message("TRACE - DPGI::getViewAxis - parallel flip: %d\n",flip); + viewAxis = TechDrawGeometry::getViewAxis(pt,axis,flip); //use default orientation + } else { +// Base::Console().Message("TRACE - DPGI::getViewAxis - skew flip: %d\n",flip); + viewAxis = TechDrawGeometry::getViewAxis(pt,axis,x,flip); + } + +// if (Type.isValue("Front")) { +// viewAxis = TechDrawGeometry::getViewAxis(pt,axis,flip); //show front in upright stance +// } else { +// const char *viewProjType = Type.getValueAsString(); +// DrawProjGroup* grp = getGroup(); +// if (grp == nullptr) { +// Base::Console().Message("TRACE - DPGI::getViewAxis - NO GROUP!!!\n"); +// return TechDrawGeometry::getViewAxis(pt,axis,flip); //too early +// } else { +// getGroup()->dumpViewDir("viewDir map"); //<<<< +// getGroup()->dumpXAxisDir("xAxisDir map"); +// Base::Vector3d x = getGroup()->getXAxisDir(viewProjType); +// Base::Vector3d x = OrientBasis.getValue(); +// viewAxis = TechDrawGeometry::getViewAxis(pt,axis,x,flip); +// } +// } + //Base::Console().Message("TRACE - DPGI::getViewAxis exits\n"); + return viewAxis; +} + +//! rotate OrientBasis by angle radians around view Direction +Base::Vector3d DrawProjGroupItem::rotated(const double angle) +{ + Base::Console().Message("TRACE - DPGI::rotated - %s/%s angle: %.3f\n",Label.getValue(),Type.getValueAsString(),angle); + Base::Vector3d line = Direction.getValue(); + Base::Vector3d oldBasis = OrientBasis.getValue(); + Base::Vector3d newBasis; + Base::Vector3d org(0.0,0.0,0.0); + Base::Matrix4D xForm; + xForm.rotLine(line,angle); + newBasis = xForm * (oldBasis); + Base::Console().Message("TRACE - DPGI::rotated - line: %s old: %s new: %s\n", + DrawUtil::formatVector(line).c_str(), + DrawUtil::formatVector(oldBasis).c_str(), + DrawUtil::formatVector(newBasis).c_str()); + if (getGroup() != nullptr) { + if (getGroup()->getException(Type.getValueAsString())) { + newBasis = newBasis * -1.0; + Base::Console().Message("TRACE - DPGI::rotated - EXCEPTION\n"); + } + } + return newBasis; +} PyObject *DrawProjGroupItem::getPyObject(void) { diff --git a/src/Mod/TechDraw/App/DrawProjGroupItem.h b/src/Mod/TechDraw/App/DrawProjGroupItem.h index 79be59c05..723c4d243 100644 --- a/src/Mod/TechDraw/App/DrawProjGroupItem.h +++ b/src/Mod/TechDraw/App/DrawProjGroupItem.h @@ -54,6 +54,7 @@ public: ~DrawProjGroupItem(); App::PropertyEnumeration Type; + App::PropertyVector OrientBasis; short mustExecute() const; /** @name methods overide Feature */ @@ -63,7 +64,10 @@ public: // virtual App::DocumentObjectExecReturn *execute(void); // TODO: Delete me too if we take out the implementation //@} - DrawProjGroup* getGroup(void); + DrawProjGroup* getGroup(void) const; + virtual gp_Ax2 getViewAxis(const Base::Vector3d& pt, + const Base::Vector3d& direction, + const bool flip=true) const override; /// returns the type name of the ViewProvider virtual const char* getViewProviderName(void) const { diff --git a/src/Mod/TechDraw/App/DrawProjectSplit.cpp b/src/Mod/TechDraw/App/DrawProjectSplit.cpp index 8cf21adf4..dccf85eb0 100644 --- a/src/Mod/TechDraw/App/DrawProjectSplit.cpp +++ b/src/Mod/TechDraw/App/DrawProjectSplit.cpp @@ -115,7 +115,8 @@ std::vector DrawProjectSplit::getEdgesForWalker(TopoDS_Shape shape, TopoDS_Shape scaledShape; scaledShape = TechDrawGeometry::scaleShape(copyShape, scale); - TechDrawGeometry::GeometryObject* go = buildGeometryObject(scaledShape,inputCenter,direction); + gp_Ax2 viewAxis = TechDrawGeometry::getViewAxis(Base::Vector3d(0.0,0.0,0.0),direction); + TechDrawGeometry::GeometryObject* go = buildGeometryObject(scaledShape,viewAxis); result = getEdges(go); delete go; @@ -123,16 +124,13 @@ std::vector DrawProjectSplit::getEdgesForWalker(TopoDS_Shape shape, } -TechDrawGeometry::GeometryObject* DrawProjectSplit::buildGeometryObject( - TopoDS_Shape shape, - gp_Pnt& inputCenter, - Base::Vector3d direction) +TechDrawGeometry::GeometryObject* DrawProjectSplit::buildGeometryObject(TopoDS_Shape shape, + gp_Ax2 viewAxis) { TechDrawGeometry::GeometryObject* geometryObject = new TechDrawGeometry::GeometryObject("DrawProjectSplit"); geometryObject->projectShape(shape, - inputCenter, - direction); + viewAxis); geometryObject->extractGeometry(TechDrawGeometry::ecHARD, //always show the hard&outline visible lines true); geometryObject->extractGeometry(TechDrawGeometry::ecOUTLINE, @@ -440,8 +438,13 @@ std::vector DrawProjectSplit::removeDuplicateEdges(std::vector getEdgesForWalker(TopoDS_Shape shape, double scale, Base::Vector3d direction); - static TechDrawGeometry::GeometryObject* buildGeometryObject(TopoDS_Shape shape, gp_Pnt& center, Base::Vector3d direction); + static TechDrawGeometry::GeometryObject* buildGeometryObject(TopoDS_Shape shape, gp_Ax2 viewAxis); static bool isOnEdge(TopoDS_Edge e, TopoDS_Vertex v, double& param, bool allowEnds = false); static std::vector splitEdges(std::vector orig, std::vector splits); diff --git a/src/Mod/TechDraw/App/DrawViewDetail.cpp b/src/Mod/TechDraw/App/DrawViewDetail.cpp index 983f99b99..81255b7a8 100644 --- a/src/Mod/TechDraw/App/DrawViewDetail.cpp +++ b/src/Mod/TechDraw/App/DrawViewDetail.cpp @@ -169,7 +169,7 @@ App::DocumentObjectExecReturn *DrawViewDetail::execute(void) 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); + gp_Ax2 viewAxis = getViewAxis(Base::Vector3d(0.0,0.0,0.0), dirDetail, false); Base::BoundBox3d bbxSource = partTopo.getBoundBox(); @@ -239,7 +239,8 @@ App::DocumentObjectExecReturn *DrawViewDetail::execute(void) TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(detail, inputCenter, scale); - geometryObject = buildGeometryObject(mirroredShape,inputCenter); + gp_Ax2 viewAxis = getViewAxis(Base::Vector3d(inputCenter.X(),inputCenter.Y(),inputCenter.Z()),Direction.getValue()); + geometryObject = buildGeometryObject(mirroredShape,viewAxis); #if MOD_TECHDRAW_HANDLE_FACES if (handleFaces()) { diff --git a/src/Mod/TechDraw/App/DrawViewMulti.cpp b/src/Mod/TechDraw/App/DrawViewMulti.cpp index 6ae44542e..a4ac2c5ec 100644 --- a/src/Mod/TechDraw/App/DrawViewMulti.cpp +++ b/src/Mod/TechDraw/App/DrawViewMulti.cpp @@ -146,7 +146,8 @@ App::DocumentObjectExecReturn *DrawViewMulti::execute(void) TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(comp, inputCenter, Scale.getValue()); - geometryObject = buildGeometryObject(mirroredShape,inputCenter); + gp_Ax2 viewAxis = getViewAxis(Base::Vector3d(inputCenter.X(),inputCenter.Y(),inputCenter.Z()),Direction.getValue()); + geometryObject = buildGeometryObject(mirroredShape,viewAxis); #if MOD_TECHDRAW_HANDLE_FACES extractFaces(); diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index 557e590db..4abec261a 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -143,7 +143,6 @@ DrawViewPart::~DrawViewPart() App::DocumentObjectExecReturn *DrawViewPart::execute(void) { - //Base::Console().Message("TRACE - DVP::execute() - %s\n",getNameInDocument()); App::DocumentObject *link = Source.getValue(); if (!link) { return new App::DocumentObjectExecReturn("FVP - No Source object linked"); @@ -157,6 +156,7 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void) if (shape.IsNull()) { return new App::DocumentObjectExecReturn("FVP - Linked shape object is empty"); } + Base::Console().Message("TRACE - DVP::execute() - %s - %s - dir: %s\n",getNameInDocument(), Label.getValue(),DrawUtil::formatVector(Direction.getValue()).c_str()); (void) DrawView::execute(); //make sure Scale is up to date @@ -171,7 +171,8 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void) inputCenter, Scale.getValue()); - geometryObject = buildGeometryObject(mirroredShape,inputCenter); + gp_Ax2 viewAxis = getViewAxis(shapeCentroid,Direction.getValue()); + geometryObject = buildGeometryObject(mirroredShape,viewAxis); #if MOD_TECHDRAW_HANDLE_FACES if (handleFaces()) { @@ -186,6 +187,9 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void) } #endif //#if MOD_TECHDRAW_HANDLE_FACES + Base::Console().Message("TRACE _ DVP::exec - %s/%s u: %s v: %s w: %s\n",getNameInDocument(),Label.getValue(), + DrawUtil::formatVector(getUDir()).c_str(), DrawUtil::formatVector(getVDir()).c_str(),DrawUtil::formatVector(getWDir()).c_str()); + return App::DocumentObject::StdReturn; } @@ -214,7 +218,7 @@ void DrawViewPart::onChanged(const App::Property* prop) } //note: slightly different than routine with same name in DrawProjectSplit -TechDrawGeometry::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape shape, gp_Pnt& inputCenter) +TechDrawGeometry::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape shape, gp_Ax2 viewAxis) { TechDrawGeometry::GeometryObject* go = new TechDrawGeometry::GeometryObject(getNameInDocument()); go->setIsoCount(IsoCount.getValue()); @@ -223,8 +227,7 @@ TechDrawGeometry::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape saveParamSpace(baseProjDir); go->projectShape(shape, - inputCenter, - Direction.getValue()); + viewAxis); go->extractGeometry(TechDrawGeometry::ecHARD, //always show the hard&outline visible lines true); go->extractGeometry(TechDrawGeometry::ecOUTLINE, @@ -358,7 +361,7 @@ void DrawViewPart::extractFaces() return; } - newEdges = DrawProjectSplit::removeDuplicateEdges(newEdges); + newEdges = DrawProjectSplit::removeDuplicateEdges(newEdges); //<<< here //find all the wires in the pile of faceEdges EdgeWalker ew; @@ -487,7 +490,7 @@ Base::Vector3d DrawViewPart::projectPoint(const Base::Vector3d& pt) const { Base::Vector3d centeredPoint = pt - shapeCentroid; Base::Vector3d direction = Direction.getValue(); - gp_Ax2 viewAxis = TechDrawGeometry::getViewAxis(centeredPoint,direction); + gp_Ax2 viewAxis = getViewAxis(centeredPoint,direction); HLRAlgo_Projector projector( viewAxis ); gp_Pnt2d prjPnt; projector.Project(gp_Pnt(centeredPoint.x,centeredPoint.y,centeredPoint.z), prjPnt); @@ -511,10 +514,23 @@ bool DrawViewPart::hasGeometry(void) const return result; } -void DrawViewPart::saveParamSpace(const Base::Vector3d& direction) +//boring here. gets more interesting in descendents. +gp_Ax2 DrawViewPart::getViewAxis(const Base::Vector3d& pt, + const Base::Vector3d& axis, + const bool flip, + const Base::Vector3d& xAxis) const { + (void)xAxis; + gp_Ax2 viewAxis = TechDrawGeometry::getViewAxis(pt,axis,flip); + return viewAxis; +} + +//this might have to be virtual for dpgi? +void DrawViewPart::saveParamSpace(const Base::Vector3d& direction, const Base::Vector3d& xAxis) +{ + (void)xAxis; Base::Vector3d origin(0.0,0.0,0.0); - gp_Ax2 viewAxis = TechDrawGeometry::getViewAxis(origin,direction); + gp_Ax2 viewAxis = getViewAxis(origin,direction); gp_Dir xdir = viewAxis.XDirection(); uDir = Base::Vector3d(xdir.X(),xdir.Y(),xdir.Z()); diff --git a/src/Mod/TechDraw/App/DrawViewPart.h b/src/Mod/TechDraw/App/DrawViewPart.h index 90936e0d3..c6d6405b0 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.h +++ b/src/Mod/TechDraw/App/DrawViewPart.h @@ -114,6 +114,10 @@ public: const Base::Vector3d& getWDir(void) const {return wDir;} //paperspace Z const Base::Vector3d& getCentroid(void) const {return shapeCentroid;} Base::Vector3d projectPoint(const Base::Vector3d& pt) const; + virtual gp_Ax2 getViewAxis(const Base::Vector3d& pt, + const Base::Vector3d& direction, + const bool flip=true, + const Base::Vector3d& xAxis=Base::Vector3d(0.0,0.0,0.0)) const; virtual short mustExecute() const; @@ -138,11 +142,11 @@ protected: Base::BoundBox3d bbox; void onChanged(const App::Property* prop); - TechDrawGeometry::GeometryObject* buildGeometryObject(TopoDS_Shape shape, gp_Pnt& center); + virtual TechDrawGeometry::GeometryObject* buildGeometryObject(TopoDS_Shape shape, gp_Ax2 viewAxis); void extractFaces(); //Projection parameter space - void saveParamSpace(const Base::Vector3d& direction); + virtual void saveParamSpace(const Base::Vector3d& direction, const Base::Vector3d& xAxis=Base::Vector3d(0.0,0.0,0.0)); Base::Vector3d uDir; //paperspace X Base::Vector3d vDir; //paperspace Y Base::Vector3d wDir; //paperspace Z diff --git a/src/Mod/TechDraw/App/DrawViewSection.cpp b/src/Mod/TechDraw/App/DrawViewSection.cpp index da9595cd3..1f97d8b77 100644 --- a/src/Mod/TechDraw/App/DrawViewSection.cpp +++ b/src/Mod/TechDraw/App/DrawViewSection.cpp @@ -228,7 +228,8 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void) TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(rawShape, inputCenter, Scale.getValue()); - geometryObject = buildGeometryObject(mirroredShape,inputCenter); //this is original shape after cut by section prism + gp_Ax2 viewAxis = getViewAxis(Base::Vector3d(inputCenter.X(),inputCenter.Y(),inputCenter.Z()),Direction.getValue()); + geometryObject = buildGeometryObject(mirroredShape,viewAxis); //this is original shape after cut by section prism #if MOD_TECHDRAW_HANDLE_FACES extractFaces(); @@ -275,7 +276,7 @@ gp_Pln DrawViewSection::getSectionPlane() const { Base::Vector3d plnPnt = SectionOrigin.getValue(); Base::Vector3d plnNorm = SectionNormal.getValue(); - gp_Ax2 viewAxis = TechDrawGeometry::getViewAxis(plnPnt,plnNorm,false); + gp_Ax2 viewAxis = getViewAxis(plnPnt,plnNorm,false); gp_Ax3 viewAxis3(viewAxis); return gp_Pln(viewAxis3); @@ -351,7 +352,7 @@ TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face, } Base::Vector3d origin(faceCenter.X(),faceCenter.Y(),faceCenter.Z()); - gp_Ax2 viewAxis = TechDrawGeometry::getViewAxis(origin,direction); + gp_Ax2 viewAxis = getViewAxis(origin,direction); HLRBRep_Algo *brep_hlr = new HLRBRep_Algo(); brep_hlr->Add(face); diff --git a/src/Mod/TechDraw/App/GeometryObject.cpp b/src/Mod/TechDraw/App/GeometryObject.cpp index a23138b99..8d87230ca 100644 --- a/src/Mod/TechDraw/App/GeometryObject.cpp +++ b/src/Mod/TechDraw/App/GeometryObject.cpp @@ -1,535 +1,572 @@ -/*************************************************************************** - * Copyright (c) 2013 Luke Parry * - * * - * 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 - -#endif // #ifndef _PreComp_ - -#include -#include - -#include -#include -#include -#include - -#include - -#include "DrawUtil.h" -#include "GeometryObject.h" -#include "DrawViewPart.h" - -using namespace TechDrawGeometry; -using namespace TechDraw; -using namespace std; - -struct EdgePoints { - gp_Pnt v1, v2; - TopoDS_Edge edge; -}; - -GeometryObject::GeometryObject(const string& parent) : - Scale(1.f), - m_parentName(parent), - m_isoCount(0) -{ -} - -GeometryObject::~GeometryObject() -{ - clear(); -} - -void GeometryObject::setScale(double value) -{ - Scale = value; -} - - -const std::vector GeometryObject::getVisibleFaceEdges(const bool smooth, const bool seam) const -{ - std::vector result; - bool smoothOK = smooth; - bool seamOK = seam; - - for (auto& e:edgeGeom) { - if (e->visible) { - switch (e->classOfEdge) { - case ecHARD: - case ecOUTLINE: - result.push_back(e); - break; - case ecSMOOTH: - if (smoothOK) { - result.push_back(e); - } - break; - case ecSEAM: - if (seamOK) { - result.push_back(e); - } - break; - default: - ; - } - } - } - return result; -} - - - -void GeometryObject::clear() -{ - for(std::vector::iterator it = edgeGeom.begin(); it != edgeGeom.end(); ++it) { - delete *it; - *it = 0; - } - - for(std::vector::iterator it = faceGeom.begin(); it != faceGeom.end(); ++it) { - delete *it; - *it = 0; - } - - for(std::vector::iterator it = vertexGeom.begin(); it != vertexGeom.end(); ++it) { - delete *it; - *it = 0; - } - - vertexGeom.clear(); - faceGeom.clear(); - edgeGeom.clear(); -} - -//!set up a hidden line remover and project a shape with it -void GeometryObject::projectShape(const TopoDS_Shape& input, - const gp_Pnt& inputCenter, - const Base::Vector3d& direction) -{ - // Clear previous Geometry - clear(); - Base::Vector3d origin(inputCenter.X(),inputCenter.Y(),inputCenter.Z()); - gp_Ax2 viewAxis = getViewAxis(origin,direction); - auto start = chrono::high_resolution_clock::now(); - - Handle_HLRBRep_Algo brep_hlr = NULL; - try { - brep_hlr = new HLRBRep_Algo(); - brep_hlr->Add(input, m_isoCount); - HLRAlgo_Projector projector( viewAxis ); - brep_hlr->Projector(projector); - brep_hlr->Update(); - brep_hlr->Hide(); - } - catch (...) { - Standard_Failure::Raise("GeometryObject::projectShape - error occurred while projecting shape"); - } - auto end = chrono::high_resolution_clock::now(); - auto diff = end - start; - double diffOut = chrono::duration (diff).count(); - Base::Console().Log("TIMING - %s GO spent: %.3f millisecs in HLRBRep_Algo & co\n",m_parentName.c_str(),diffOut); - - try { - HLRBRep_HLRToShape hlrToShape(brep_hlr); - - visHard = hlrToShape.VCompound(); - visSmooth = hlrToShape.Rg1LineVCompound(); - visSeam = hlrToShape.RgNLineVCompound(); - visOutline = hlrToShape.OutLineVCompound(); - visIso = hlrToShape.IsoLineVCompound(); - hidHard = hlrToShape.HCompound(); - hidSmooth = hlrToShape.Rg1LineHCompound(); - hidSeam = hlrToShape.RgNLineHCompound(); - hidOutline = hlrToShape.OutLineHCompound(); - hidIso = hlrToShape.IsoLineHCompound(); - -//need these 3d curves to prevent "zero edges" later - BRepLib::BuildCurves3d(visHard); - BRepLib::BuildCurves3d(visSmooth); - BRepLib::BuildCurves3d(visSeam); - BRepLib::BuildCurves3d(visOutline); - BRepLib::BuildCurves3d(visIso); - BRepLib::BuildCurves3d(hidHard); - BRepLib::BuildCurves3d(hidSmooth); - BRepLib::BuildCurves3d(hidSeam); - BRepLib::BuildCurves3d(hidOutline); - BRepLib::BuildCurves3d(hidIso); - } - catch (...) { - Standard_Failure::Raise("GeometryObject::projectShape - error occurred while extracting edges"); - } - -} - -//!add edges meeting filter criteria for category, visibility -void GeometryObject::extractGeometry(edgeClass category, bool visible) -{ - TopoDS_Shape filtEdges; - if (visible) { - switch (category) { - case ecHARD: - filtEdges = visHard; - break; - case ecOUTLINE: - filtEdges = visOutline; - break; - case ecSMOOTH: - filtEdges = visSmooth; - break; - case ecSEAM: - filtEdges = visSeam; - break; - case ecUVISO: - filtEdges = visIso; - break; - default: - Base::Console().Warning("GeometryObject::ExtractGeometry - unsupported visible edgeClass: %d\n",category); - return; - } - } else { - switch (category) { - case ecHARD: - filtEdges = hidHard; - break; - case ecOUTLINE: - filtEdges = hidOutline; - break; - case ecSMOOTH: - filtEdges = hidSmooth; - break; - case ecSEAM: - filtEdges = hidSeam; - break; - case ecUVISO: - filtEdges = hidIso; - break; - default: - Base::Console().Warning("GeometryObject::ExtractGeometry - unsupported hidden edgeClass: %d\n",category); - return; - } - } - - addGeomFromCompound(filtEdges, category, visible); -} - -//! update edgeGeom and vertexGeom from Compound of edges -void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass category, bool visible) -{ - if(edgeCompound.IsNull()) { - Base::Console().Log("TechDraw::GeometryObject::addGeomFromCompound edgeCompound is NULL\n"); - return; // There is no OpenCascade Geometry to be calculated - } - - BaseGeom* base; - TopExp_Explorer edges(edgeCompound, TopAbs_EDGE); - for (int i = 1 ; edges.More(); edges.Next(),i++) { - const TopoDS_Edge& edge = TopoDS::Edge(edges.Current()); - if (edge.IsNull()) { - //Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is NULL\n",i); - continue; - } - if (DrawUtil::isZeroEdge(edge)) { - Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is zeroEdge\n",i); - continue; - } - - base = BaseGeom::baseFactory(edge); - if (base == nullptr) { - Base::Console().Message("Error - GO::addGeomFromCompound - baseFactory failed for edge: %d\n",i); - throw Base::Exception("GeometryObject::addGeomFromCompound - baseFactory failed"); - } - base->classOfEdge = category; - base->visible = visible; - edgeGeom.push_back(base); - - //add vertices of new edge if not already in list - if (visible) { - BaseGeom* lastAdded = edgeGeom.back(); - bool v1Add = true, v2Add = true; - bool c1Add = true; - TechDrawGeometry::Vertex* v1 = new TechDrawGeometry::Vertex(lastAdded->getStartPoint()); - TechDrawGeometry::Vertex* v2 = new TechDrawGeometry::Vertex(lastAdded->getEndPoint()); - TechDrawGeometry::Circle* circle = dynamic_cast(lastAdded); - TechDrawGeometry::Vertex* c1 = nullptr; - if (circle) { - c1 = new TechDrawGeometry::Vertex(circle->center); - c1->isCenter = true; - c1->visible = true; - } - - std::vector::iterator itVertex = vertexGeom.begin(); - for (; itVertex != vertexGeom.end(); itVertex++) { - if ((*itVertex)->isEqual(v1,Precision::Confusion())) { - v1Add = false; - } - if ((*itVertex)->isEqual(v2,Precision::Confusion())) { - v2Add = false; - } - if (circle) { - if ((*itVertex)->isEqual(c1,Precision::Confusion())) { - c1Add = false; - } - } - - } - if (v1Add) { - vertexGeom.push_back(v1); - v1->visible = true; - } else { - delete v1; - } - if (v2Add) { - vertexGeom.push_back(v2); - v2->visible = true; - } else { - delete v2; - } - - if (circle) { - if (c1Add) { - vertexGeom.push_back(c1); - c1->visible = true; - } else { - delete c1; - } - } - } - } //end TopExp -} - -//! empty Face geometry -void GeometryObject::clearFaceGeom() -{ - faceGeom.clear(); -} - -//! add a Face to Face Geometry -void GeometryObject::addFaceGeom(Face* f) -{ - faceGeom.push_back(f); -} - - -bool GeometryObject::isWithinArc(double theta, double first, - double last, bool cw) const -{ - if (fabs(last - first) >= 2 * M_PI) { - return true; - } - - // Put params within [0, 2*pi) - not totally sure this is necessary - theta = fmod(theta, 2 * M_PI); - if (theta < 0) { - theta += 2 * M_PI; - } - - first = fmod(first, 2 * M_PI); - if (first < 0) { - first += 2 * M_PI; - } - - last = fmod(last, 2 * M_PI); - if (last < 0) { - last += 2 * M_PI; - } - - if (cw) { - if (first > last) { - return theta <= first && theta >= last; - } else { - return theta <= first || theta >= last; - } - } else { - if (first > last) { - return theta >= first || theta <= last; - } else { - return theta >= first && theta <= last; - } - } -} - -Base::BoundBox3d GeometryObject::calcBoundingBox() const -{ - Bnd_Box testBox; - testBox.SetGap(0.0); - for (std::vector::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; -} - -//! does this GeometryObject already have this vertex -bool GeometryObject::findVertex(Base::Vector2d v) -{ - bool found = false; - std::vector::iterator it = vertexGeom.begin(); - for (; it != vertexGeom.end(); it++) { - double dist = (v - (*it)->pnt).Length(); - if (dist < Precision::Confusion()) { - found = true; - break; - } - } - return found; -} - -/// utility non-class member functions -//! gets a coordinate system -gp_Ax2 TechDrawGeometry::getViewAxis(const Base::Vector3d origin, - const Base::Vector3d& direction, - const bool flip) -{ - gp_Pnt inputCenter(origin.x,origin.y,origin.z); - Base::Vector3d stdZ(0.0,0.0,1.0); - Base::Vector3d flipDirection(direction.x,-direction.y,direction.z); - if (!flip) { - flipDirection = Base::Vector3d(direction.x,direction.y,direction.z); - } - Base::Vector3d cross = flipDirection; - //special cases - if (flipDirection == stdZ) { - cross = Base::Vector3d(1.0,0.0,0.0); - } else if (flipDirection == (stdZ * -1.0)) { - cross = Base::Vector3d(1.0,0.0,0.0); - } else { - cross.Normalize(); - cross = cross.Cross(stdZ); - } - gp_Ax2 viewAxis; - viewAxis = gp_Ax2(inputCenter, - gp_Dir(flipDirection.x, flipDirection.y, flipDirection.z), - gp_Dir(cross.x, cross.y, cross.z)); - return viewAxis; -} - - - -//! Returns the centroid of shape, as viewed according to direction -gp_Pnt TechDrawGeometry::findCentroid(const TopoDS_Shape &shape, - const Base::Vector3d &direction) -{ - Base::Vector3d origin(0.0,0.0,0.0); - gp_Ax2 viewAxis = getViewAxis(origin,direction); - - gp_Trsf tempTransform; - tempTransform.SetTransformation(viewAxis); - BRepBuilderAPI_Transform builder(shape, tempTransform); - - Bnd_Box tBounds; - BRepBndLib::Add(builder.Shape(), tBounds); - - tBounds.SetGap(0.0); - Standard_Real xMin, yMin, zMin, xMax, yMax, zMax; - tBounds.Get(xMin, yMin, zMin, xMax, yMax, zMax); - - Standard_Real x = (xMin + xMax) / 2.0, - y = (yMin + yMax) / 2.0, - z = (zMin + zMax) / 2.0; - - // Get centroid back into object space - tempTransform.Inverted().Transforms(x, y, z); - - return gp_Pnt(x, y, z); -} - -//!scales & mirrors a shape about a center -TopoDS_Shape TechDrawGeometry::mirrorShape(const TopoDS_Shape &input, - const gp_Pnt& inputCenter, - double scale) -{ - TopoDS_Shape transShape; - try { - // Make tempTransform scale the object around it's centre point and - // mirror about the Y axis - gp_Trsf tempTransform; - tempTransform.SetScale(inputCenter, scale); - gp_Trsf mirrorTransform; - mirrorTransform.SetMirror( gp_Ax2(inputCenter, gp_Dir(0, 1, 0)) ); - tempTransform.Multiply(mirrorTransform); - - // Apply that transform to the shape. This should preserve the centre. - BRepBuilderAPI_Transform mkTrf(input, tempTransform); - transShape = mkTrf.Shape(); - } - catch (...) { - Base::Console().Log("GeometryObject::mirrorShape - mirror/scale failed.\n"); - return transShape; - } - return transShape; -} - -//!scales a shape about a origin -TopoDS_Shape TechDrawGeometry::scaleShape(const TopoDS_Shape &input, - double scale) -{ - TopoDS_Shape transShape; - try { - gp_Trsf scaleTransform; - scaleTransform.SetScale(gp_Pnt(0,0,0), scale); - - BRepBuilderAPI_Transform mkTrf(input, scaleTransform); - transShape = mkTrf.Shape(); - } - catch (...) { - Base::Console().Log("GeometryObject::scaleShape - scale failed.\n"); - return transShape; - } - return transShape; -} +/*************************************************************************** + * Copyright (c) 2013 Luke Parry * + * * + * 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 + +#endif // #ifndef _PreComp_ + +#include +#include + +#include +#include +#include +#include + +#include + +#include "DrawUtil.h" +#include "GeometryObject.h" +#include "DrawViewPart.h" + +using namespace TechDrawGeometry; +using namespace TechDraw; +using namespace std; + +struct EdgePoints { + gp_Pnt v1, v2; + TopoDS_Edge edge; +}; + +GeometryObject::GeometryObject(const string& parent) : + Scale(1.f), + m_parentName(parent), + m_isoCount(0) +{ +} + +GeometryObject::~GeometryObject() +{ + clear(); +} + +void GeometryObject::setScale(double value) +{ + Scale = value; +} + + +const std::vector GeometryObject::getVisibleFaceEdges(const bool smooth, const bool seam) const +{ + std::vector result; + bool smoothOK = smooth; + bool seamOK = seam; + + for (auto& e:edgeGeom) { + if (e->visible) { + switch (e->classOfEdge) { + case ecHARD: + case ecOUTLINE: + result.push_back(e); + break; + case ecSMOOTH: + if (smoothOK) { + result.push_back(e); + } + break; + case ecSEAM: + if (seamOK) { + result.push_back(e); + } + break; + default: + ; + } + } + } + return result; +} + + + +void GeometryObject::clear() +{ + for(std::vector::iterator it = edgeGeom.begin(); it != edgeGeom.end(); ++it) { + delete *it; + *it = 0; + } + + for(std::vector::iterator it = faceGeom.begin(); it != faceGeom.end(); ++it) { + delete *it; + *it = 0; + } + + for(std::vector::iterator it = vertexGeom.begin(); it != vertexGeom.end(); ++it) { + delete *it; + *it = 0; + } + + vertexGeom.clear(); + faceGeom.clear(); + edgeGeom.clear(); +} + +//!set up a hidden line remover and project a shape with it +void GeometryObject::projectShape(const TopoDS_Shape& input, + const gp_Ax2 viewAxis) +{ + // Clear previous Geometry + clear(); + +//******* + gp_Dir x = viewAxis.XDirection(); + gp_Dir y = viewAxis.YDirection(); + gp_Dir z = viewAxis.Direction(); + Base::Vector3d vx(x.X(),x.Y(),x.Z()); + Base::Vector3d vy(y.X(),y.Y(),y.Z()); + Base::Vector3d vz(z.X(),z.Y(),z.Z()); + Base::Console().Message("TRACE - GO::projectShape - %s viewAxis x: %s y: %s Z: %s\n",m_parentName.c_str(), + DrawUtil::formatVector(vx).c_str(), DrawUtil::formatVector(vy).c_str(), DrawUtil::formatVector(vz).c_str()); +//******* + + auto start = chrono::high_resolution_clock::now(); + + Handle_HLRBRep_Algo brep_hlr = NULL; + try { + brep_hlr = new HLRBRep_Algo(); + brep_hlr->Add(input, m_isoCount); + HLRAlgo_Projector projector( viewAxis ); + brep_hlr->Projector(projector); + brep_hlr->Update(); + brep_hlr->Hide(); + } + catch (...) { + Standard_Failure::Raise("GeometryObject::projectShape - error occurred while projecting shape"); + } + auto end = chrono::high_resolution_clock::now(); + auto diff = end - start; + double diffOut = chrono::duration (diff).count(); + Base::Console().Log("TIMING - %s GO spent: %.3f millisecs in HLRBRep_Algo & co\n",m_parentName.c_str(),diffOut); + + try { + HLRBRep_HLRToShape hlrToShape(brep_hlr); + + visHard = hlrToShape.VCompound(); + visSmooth = hlrToShape.Rg1LineVCompound(); + visSeam = hlrToShape.RgNLineVCompound(); + visOutline = hlrToShape.OutLineVCompound(); + visIso = hlrToShape.IsoLineVCompound(); + hidHard = hlrToShape.HCompound(); + hidSmooth = hlrToShape.Rg1LineHCompound(); + hidSeam = hlrToShape.RgNLineHCompound(); + hidOutline = hlrToShape.OutLineHCompound(); + hidIso = hlrToShape.IsoLineHCompound(); + +//need these 3d curves to prevent "zero edges" later + BRepLib::BuildCurves3d(visHard); + BRepLib::BuildCurves3d(visSmooth); + BRepLib::BuildCurves3d(visSeam); + BRepLib::BuildCurves3d(visOutline); + BRepLib::BuildCurves3d(visIso); + BRepLib::BuildCurves3d(hidHard); + BRepLib::BuildCurves3d(hidSmooth); + BRepLib::BuildCurves3d(hidSeam); + BRepLib::BuildCurves3d(hidOutline); + BRepLib::BuildCurves3d(hidIso); + } + catch (...) { + Standard_Failure::Raise("GeometryObject::projectShape - error occurred while extracting edges"); + } + +} + +//!add edges meeting filter criteria for category, visibility +void GeometryObject::extractGeometry(edgeClass category, bool visible) +{ + TopoDS_Shape filtEdges; + if (visible) { + switch (category) { + case ecHARD: + filtEdges = visHard; + break; + case ecOUTLINE: + filtEdges = visOutline; + break; + case ecSMOOTH: + filtEdges = visSmooth; + break; + case ecSEAM: + filtEdges = visSeam; + break; + case ecUVISO: + filtEdges = visIso; + break; + default: + Base::Console().Warning("GeometryObject::ExtractGeometry - unsupported visible edgeClass: %d\n",category); + return; + } + } else { + switch (category) { + case ecHARD: + filtEdges = hidHard; + break; + case ecOUTLINE: + filtEdges = hidOutline; + break; + case ecSMOOTH: + filtEdges = hidSmooth; + break; + case ecSEAM: + filtEdges = hidSeam; + break; + case ecUVISO: + filtEdges = hidIso; + break; + default: + Base::Console().Warning("GeometryObject::ExtractGeometry - unsupported hidden edgeClass: %d\n",category); + return; + } + } + + addGeomFromCompound(filtEdges, category, visible); +} + +//! update edgeGeom and vertexGeom from Compound of edges +void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass category, bool visible) +{ + if(edgeCompound.IsNull()) { + Base::Console().Log("TechDraw::GeometryObject::addGeomFromCompound edgeCompound is NULL\n"); + return; // There is no OpenCascade Geometry to be calculated + } + + BaseGeom* base; + TopExp_Explorer edges(edgeCompound, TopAbs_EDGE); + for (int i = 1 ; edges.More(); edges.Next(),i++) { + const TopoDS_Edge& edge = TopoDS::Edge(edges.Current()); + if (edge.IsNull()) { + //Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is NULL\n",i); + continue; + } + if (DrawUtil::isZeroEdge(edge)) { + Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is zeroEdge\n",i); + continue; + } + + base = BaseGeom::baseFactory(edge); + if (base == nullptr) { + Base::Console().Message("Error - GO::addGeomFromCompound - baseFactory failed for edge: %d\n",i); + throw Base::Exception("GeometryObject::addGeomFromCompound - baseFactory failed"); + } + base->classOfEdge = category; + base->visible = visible; + edgeGeom.push_back(base); + + //add vertices of new edge if not already in list + if (visible) { + BaseGeom* lastAdded = edgeGeom.back(); + bool v1Add = true, v2Add = true; + bool c1Add = true; + TechDrawGeometry::Vertex* v1 = new TechDrawGeometry::Vertex(lastAdded->getStartPoint()); + TechDrawGeometry::Vertex* v2 = new TechDrawGeometry::Vertex(lastAdded->getEndPoint()); + TechDrawGeometry::Circle* circle = dynamic_cast(lastAdded); + TechDrawGeometry::Vertex* c1 = nullptr; + if (circle) { + c1 = new TechDrawGeometry::Vertex(circle->center); + c1->isCenter = true; + c1->visible = true; + } + + std::vector::iterator itVertex = vertexGeom.begin(); + for (; itVertex != vertexGeom.end(); itVertex++) { + if ((*itVertex)->isEqual(v1,Precision::Confusion())) { + v1Add = false; + } + if ((*itVertex)->isEqual(v2,Precision::Confusion())) { + v2Add = false; + } + if (circle) { + if ((*itVertex)->isEqual(c1,Precision::Confusion())) { + c1Add = false; + } + } + + } + if (v1Add) { + vertexGeom.push_back(v1); + v1->visible = true; + } else { + delete v1; + } + if (v2Add) { + vertexGeom.push_back(v2); + v2->visible = true; + } else { + delete v2; + } + + if (circle) { + if (c1Add) { + vertexGeom.push_back(c1); + c1->visible = true; + } else { + delete c1; + } + } + } + } //end TopExp +} + +//! empty Face geometry +void GeometryObject::clearFaceGeom() +{ + faceGeom.clear(); +} + +//! add a Face to Face Geometry +void GeometryObject::addFaceGeom(Face* f) +{ + faceGeom.push_back(f); +} + + +bool GeometryObject::isWithinArc(double theta, double first, + double last, bool cw) const +{ + if (fabs(last - first) >= 2 * M_PI) { + return true; + } + + // Put params within [0, 2*pi) - not totally sure this is necessary + theta = fmod(theta, 2 * M_PI); + if (theta < 0) { + theta += 2 * M_PI; + } + + first = fmod(first, 2 * M_PI); + if (first < 0) { + first += 2 * M_PI; + } + + last = fmod(last, 2 * M_PI); + if (last < 0) { + last += 2 * M_PI; + } + + if (cw) { + if (first > last) { + return theta <= first && theta >= last; + } else { + return theta <= first || theta >= last; + } + } else { + if (first > last) { + return theta >= first || theta <= last; + } else { + return theta >= first && theta <= last; + } + } +} + +Base::BoundBox3d GeometryObject::calcBoundingBox() const +{ + Bnd_Box testBox; + testBox.SetGap(0.0); + for (std::vector::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; +} + +//! does this GeometryObject already have this vertex +bool GeometryObject::findVertex(Base::Vector2d v) +{ + bool found = false; + std::vector::iterator it = vertexGeom.begin(); + for (; it != vertexGeom.end(); it++) { + double dist = (v - (*it)->pnt).Length(); + if (dist < Precision::Confusion()) { + found = true; + break; + } + } + return found; +} + + +//"Top" X should == "Front" X for front = [front,rear] +//"Top" X should == "Front" X for front = [right] +//"Top" X should == "Front" -X for front = [left] +//"Top" X should == "Front" X for front = [top,bottom] +//view XAxis == anchor XAxis except +// anchor.ProjDir = (-1,0,0) then +// view XAxis == -Anchor XAxis + + +/// utility non-class member functions +//! gets a coordinate system that matches view system used in 3D with +Z up (or +Y up if neccessary) +//! used for individual views, but not secondary views in projection groups +gp_Ax2 TechDrawGeometry::getViewAxis(const Base::Vector3d origin, + const Base::Vector3d& direction, + const bool flip) +{ + gp_Pnt inputCenter(origin.x,origin.y,origin.z); + Base::Vector3d stdZ(0.0,0.0,1.0); + Base::Vector3d flipDirection(direction.x,-direction.y,direction.z); + if (!flip) { + flipDirection = Base::Vector3d(direction.x,direction.y,direction.z); + } + Base::Vector3d cross = flipDirection; + //special cases + if (flipDirection == stdZ) { + cross = Base::Vector3d(1.0,0.0,0.0); + } else if (flipDirection == (stdZ * -1.0)) { + cross = Base::Vector3d(1.0,0.0,0.0); + } else { + cross.Normalize(); + cross = cross.Cross(stdZ); + } + gp_Ax2 viewAxis; + viewAxis = gp_Ax2(inputCenter, + gp_Dir(flipDirection.x, flipDirection.y, flipDirection.z), +// gp_Dir(1.0, 1.0, 0.0)); + gp_Dir(cross.x, cross.y, cross.z)); + return viewAxis; +} + +//! gets a coordinate system specified by Z and X directions +gp_Ax2 TechDrawGeometry::getViewAxis(const Base::Vector3d origin, + const Base::Vector3d& direction, + const Base::Vector3d& xAxis, + const bool flip) +{ + gp_Pnt inputCenter(origin.x,origin.y,origin.z); + Base::Vector3d flipDirection(direction.x,-direction.y,direction.z); + if (!flip) { + flipDirection = Base::Vector3d(direction.x,direction.y,direction.z); + } + gp_Ax2 viewAxis; + viewAxis = gp_Ax2(inputCenter, + gp_Dir(flipDirection.x, flipDirection.y, flipDirection.z), + gp_Dir(xAxis.x, xAxis.y, xAxis.z)); + return viewAxis; +} + +//! Returns the centroid of shape, as viewed according to direction +gp_Pnt TechDrawGeometry::findCentroid(const TopoDS_Shape &shape, + const Base::Vector3d &direction) +{ + Base::Vector3d origin(0.0,0.0,0.0); + gp_Ax2 viewAxis = getViewAxis(origin,direction); + + gp_Trsf tempTransform; + tempTransform.SetTransformation(viewAxis); + BRepBuilderAPI_Transform builder(shape, tempTransform); + + Bnd_Box tBounds; + BRepBndLib::Add(builder.Shape(), tBounds); + + tBounds.SetGap(0.0); + Standard_Real xMin, yMin, zMin, xMax, yMax, zMax; + tBounds.Get(xMin, yMin, zMin, xMax, yMax, zMax); + + Standard_Real x = (xMin + xMax) / 2.0, + y = (yMin + yMax) / 2.0, + z = (zMin + zMax) / 2.0; + + // Get centroid back into object space + tempTransform.Inverted().Transforms(x, y, z); + + return gp_Pnt(x, y, z); +} + +//!scales & mirrors a shape about a center +TopoDS_Shape TechDrawGeometry::mirrorShape(const TopoDS_Shape &input, + const gp_Pnt& inputCenter, + double scale) +{ + TopoDS_Shape transShape; + try { + // Make tempTransform scale the object around it's centre point and + // mirror about the Y axis + gp_Trsf tempTransform; + tempTransform.SetScale(inputCenter, scale); + gp_Trsf mirrorTransform; + mirrorTransform.SetMirror( gp_Ax2(inputCenter, gp_Dir(0, 1, 0)) ); + tempTransform.Multiply(mirrorTransform); + + // Apply that transform to the shape. This should preserve the centre. + BRepBuilderAPI_Transform mkTrf(input, tempTransform); + transShape = mkTrf.Shape(); + } + catch (...) { + Base::Console().Log("GeometryObject::mirrorShape - mirror/scale failed.\n"); + return transShape; + } + return transShape; +} + +//!scales a shape about a origin +TopoDS_Shape TechDrawGeometry::scaleShape(const TopoDS_Shape &input, + double scale) +{ + TopoDS_Shape transShape; + try { + gp_Trsf scaleTransform; + scaleTransform.SetScale(gp_Pnt(0,0,0), scale); + + BRepBuilderAPI_Transform mkTrf(input, scaleTransform); + transShape = mkTrf.Shape(); + } + catch (...) { + Base::Console().Log("GeometryObject::scaleShape - scale failed.\n"); + return transShape; + } + return transShape; +} diff --git a/src/Mod/TechDraw/App/GeometryObject.h b/src/Mod/TechDraw/App/GeometryObject.h index 40aa56ea8..f52081b67 100644 --- a/src/Mod/TechDraw/App/GeometryObject.h +++ b/src/Mod/TechDraw/App/GeometryObject.h @@ -1,126 +1,130 @@ -/*************************************************************************** - * Copyright (c) 2013 Luke Parry * - * * - * 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 _TECHDRAW_GEOMETRYOBJECT_H -#define _TECHDRAW_GEOMETRYOBJECT_H - -#include -#include -#include - -#include -#include -#include - -#include "Geometry.h" - -namespace TechDraw -{ -class DrawViewPart; -class DrawView; -} - -namespace TechDrawGeometry -{ - -//! scales & mirrors a shape about a center -TopoDS_Shape TechDrawExport mirrorShape(const TopoDS_Shape &input, - const gp_Pnt& inputCenter, - double scale); -TopoDS_Shape TechDrawExport scaleShape(const TopoDS_Shape &input, - double scale); - -//! Returns the centroid of shape, as viewed according to direction -gp_Pnt TechDrawExport findCentroid(const TopoDS_Shape &shape, - const Base::Vector3d &direction); - -gp_Ax2 TechDrawExport getViewAxis(const Base::Vector3d origin, - const Base::Vector3d& direction, - const bool flip=true); - -class TechDrawExport GeometryObject -{ -public: - /// Constructor - GeometryObject(const std::string& parent); - virtual ~GeometryObject(); - - void clear(); - - void setScale(double value); - - //! Returns 2D bounding box - Base::BoundBox3d calcBoundingBox() const; - - const std::vector & getVertexGeometry() const { return vertexGeom; }; - const std::vector & getEdgeGeometry() const { return edgeGeom; }; - const std::vector getVisibleFaceEdges(bool smooth, bool seam) const; - const std::vector & getFaceGeometry() const { return faceGeom; }; - - void projectShape(const TopoDS_Shape &input, - const gp_Pnt& inputCenter, - const Base::Vector3d &direction); - void extractGeometry(edgeClass category, bool visible); - void addFaceGeom(Face * f); - void clearFaceGeom(); - void setIsoCount(int i) { m_isoCount = i; } - void setParentName(std::string n); //for debug messages - -protected: - //HLR output - TopoDS_Shape visHard; - TopoDS_Shape visOutline; - TopoDS_Shape visSmooth; - TopoDS_Shape visSeam; - TopoDS_Shape visIso; - TopoDS_Shape hidHard; - TopoDS_Shape hidOutline; - TopoDS_Shape hidSmooth; - TopoDS_Shape hidSeam; - TopoDS_Shape hidIso; - - void addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass category, bool visible); - - - //similar function in Geometry? - /*! - * Returns true iff angle theta is in [first, last], where the arc goes - * clockwise (cw=true) or counterclockwise (cw=false) from first to last. - */ - bool isWithinArc(double theta, double first, double last, bool cw) const; - - // Geometry - std::vector edgeGeom; - std::vector vertexGeom; - std::vector faceGeom; - - bool findVertex(Base::Vector2d v); - - double Scale; - - std::string m_parentName; - int m_isoCount; -}; - -} //namespace TechDrawGeometry - -#endif +/*************************************************************************** + * Copyright (c) 2013 Luke Parry * + * * + * 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 _TECHDRAW_GEOMETRYOBJECT_H +#define _TECHDRAW_GEOMETRYOBJECT_H + +#include +#include +#include + +#include +#include +#include + +#include "Geometry.h" + +namespace TechDraw +{ +class DrawViewPart; +class DrawView; +} + +namespace TechDrawGeometry +{ + +//! scales & mirrors a shape about a center +TopoDS_Shape TechDrawExport mirrorShape(const TopoDS_Shape &input, + const gp_Pnt& inputCenter, + double scale); +TopoDS_Shape TechDrawExport scaleShape(const TopoDS_Shape &input, + double scale); + +//! Returns the centroid of shape, as viewed according to direction +gp_Pnt TechDrawExport findCentroid(const TopoDS_Shape &shape, + const Base::Vector3d &direction); + +gp_Ax2 TechDrawExport getViewAxis(const Base::Vector3d origin, + const Base::Vector3d& direction, + const bool flip=true); +gp_Ax2 TechDrawExport getViewAxis(const Base::Vector3d origin, + const Base::Vector3d& direction, + const Base::Vector3d& xAxis, + const bool flip=true); + +class TechDrawExport GeometryObject +{ +public: + /// Constructor + GeometryObject(const std::string& parent); + virtual ~GeometryObject(); + + void clear(); + + void setScale(double value); + + //! Returns 2D bounding box + Base::BoundBox3d calcBoundingBox() const; + + const std::vector & getVertexGeometry() const { return vertexGeom; }; + const std::vector & getEdgeGeometry() const { return edgeGeom; }; + const std::vector getVisibleFaceEdges(bool smooth, bool seam) const; + const std::vector & getFaceGeometry() const { return faceGeom; }; + + void projectShape(const TopoDS_Shape &input, + const gp_Ax2 viewAxis); + + void extractGeometry(edgeClass category, bool visible); + void addFaceGeom(Face * f); + void clearFaceGeom(); + void setIsoCount(int i) { m_isoCount = i; } + void setParentName(std::string n); //for debug messages + +protected: + //HLR output + TopoDS_Shape visHard; + TopoDS_Shape visOutline; + TopoDS_Shape visSmooth; + TopoDS_Shape visSeam; + TopoDS_Shape visIso; + TopoDS_Shape hidHard; + TopoDS_Shape hidOutline; + TopoDS_Shape hidSmooth; + TopoDS_Shape hidSeam; + TopoDS_Shape hidIso; + + void addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass category, bool visible); + + + //similar function in Geometry? + /*! + * Returns true iff angle theta is in [first, last], where the arc goes + * clockwise (cw=true) or counterclockwise (cw=false) from first to last. + */ + bool isWithinArc(double theta, double first, double last, bool cw) const; + + // Geometry + std::vector edgeGeom; + std::vector vertexGeom; + std::vector faceGeom; + + bool findVertex(Base::Vector2d v); + + double Scale; + + std::string m_parentName; + int m_isoCount; +}; + +} //namespace TechDrawGeometry + +#endif