[TD]Complex Section - initial implementation
This commit is contained in:
@@ -24,8 +24,9 @@
|
||||
#include <Base/Interpreter.h>
|
||||
#include <Base/PyObjectBase.h>
|
||||
|
||||
#include "Cosmetic.h"
|
||||
#include "CosmeticExtension.h"
|
||||
#include "Cosmetic.h"
|
||||
#include "DrawComplexSection.h"
|
||||
#include "DrawGeomHatch.h"
|
||||
#include "DrawHatch.h"
|
||||
#include "DrawLeaderLine.h"
|
||||
@@ -37,7 +38,6 @@
|
||||
#include "DrawSVGTemplate.h"
|
||||
#include "DrawTile.h"
|
||||
#include "DrawTileWeld.h"
|
||||
#include "DrawView.h"
|
||||
#include "DrawViewAnnotation.h"
|
||||
#include "DrawViewArch.h"
|
||||
#include "DrawViewBalloon.h"
|
||||
@@ -47,8 +47,8 @@
|
||||
#include "DrawViewDimension.h"
|
||||
#include "DrawViewDimExtent.h"
|
||||
#include "DrawViewDraft.h"
|
||||
#include "DrawView.h"
|
||||
#include "DrawViewImage.h"
|
||||
#include "DrawViewMulti.h"
|
||||
#include "DrawViewPart.h"
|
||||
#include "DrawViewSection.h"
|
||||
#include "DrawViewSpreadsheet.h"
|
||||
@@ -62,6 +62,7 @@
|
||||
#include "PropertyGeomFormatList.h"
|
||||
|
||||
|
||||
|
||||
namespace TechDraw {
|
||||
extern PyObject* initModule();
|
||||
}
|
||||
@@ -90,7 +91,7 @@ PyMOD_INIT_FUNC(TechDraw)
|
||||
TechDraw::DrawViewSpreadsheet ::init();
|
||||
|
||||
TechDraw::DrawViewSection ::init();
|
||||
TechDraw::DrawViewMulti ::init();
|
||||
TechDraw::DrawComplexSection ::init();
|
||||
TechDraw::DrawViewDimension ::init();
|
||||
TechDraw::DrawViewDimExtent ::init();
|
||||
TechDraw::LandmarkDimension ::init();
|
||||
@@ -134,7 +135,8 @@ PyMOD_INIT_FUNC(TechDraw)
|
||||
TechDraw::DrawPagePython ::init();
|
||||
TechDraw::DrawViewPython ::init();
|
||||
TechDraw::DrawViewPartPython ::init();
|
||||
TechDraw::DrawViewMultiPython ::init();
|
||||
TechDraw::DrawViewSectionPython::init();
|
||||
TechDraw::DrawComplexSectionPython ::init();
|
||||
TechDraw::DrawTemplatePython ::init();
|
||||
TechDraw::DrawViewSymbolPython::init();
|
||||
TechDraw::DrawLeaderLinePython::init();
|
||||
|
||||
@@ -75,6 +75,8 @@ generate_from_xml(CosmeticExtensionPy)
|
||||
SET(Draw_SRCS
|
||||
DrawPage.cpp
|
||||
DrawPage.h
|
||||
DrawComplexSection.cpp
|
||||
DrawComplexSection.h
|
||||
DrawView.cpp
|
||||
DrawView.h
|
||||
DrawViewPart.cpp
|
||||
|
||||
1205
src/Mod/TechDraw/App/DrawComplexSection.cpp
Normal file
1205
src/Mod/TechDraw/App/DrawComplexSection.cpp
Normal file
File diff suppressed because it is too large
Load Diff
129
src/Mod/TechDraw/App/DrawComplexSection.h
Normal file
129
src/Mod/TechDraw/App/DrawComplexSection.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 WandererFan <wandererfan@gmail.com> *
|
||||
* *
|
||||
* 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 DrawComplexSection_h_
|
||||
#define DrawComplexSection_h_
|
||||
|
||||
#include <Mod/TechDraw/TechDrawGlobal.h>
|
||||
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
#include "DrawViewSection.h"
|
||||
|
||||
namespace TechDraw
|
||||
{
|
||||
|
||||
//changes in direction of complex section line
|
||||
class ChangePoint
|
||||
{
|
||||
public:
|
||||
ChangePoint(QPointF location, QPointF preDirection, QPointF postDirection);
|
||||
ChangePoint(gp_Pnt location, gp_Dir preDirection, gp_Dir postDirection);
|
||||
~ChangePoint() = default;
|
||||
|
||||
QPointF getLocation() const { return m_location; }
|
||||
QPointF getPreDirection() const { return m_preDirection; }
|
||||
QPointF getPostDirection() const { return m_postDirection; }
|
||||
void scale(double scaleFactor);
|
||||
|
||||
private:
|
||||
QPointF m_location;
|
||||
QPointF m_preDirection;
|
||||
QPointF m_postDirection;
|
||||
};
|
||||
|
||||
using ChangePointVector = std::vector<ChangePoint>;
|
||||
|
||||
class TechDrawExport DrawComplexSection : public DrawViewSection
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(Part::DrawComplexSection);
|
||||
|
||||
public:
|
||||
DrawComplexSection();
|
||||
~DrawComplexSection() = default;
|
||||
|
||||
App::PropertyLink CuttingToolWireObject;
|
||||
App::PropertyEnumeration ProjectionStrategy; //Single or Piecewise
|
||||
|
||||
TopoDS_Shape getShapeToCut() override;
|
||||
TopoDS_Shape makeCuttingTool(double dMax) override;
|
||||
gp_Ax2 getCSFromBase(const std::string sectionName) const override;
|
||||
bool isBaseValid() const override;
|
||||
TopoDS_Compound findSectionPlaneIntersections(const TopoDS_Shape& cutShape) override;
|
||||
TopoDS_Shape prepareShape(const TopoDS_Shape& cutShape,
|
||||
double shapeSize) override;
|
||||
TopoDS_Shape getShapeToPrepare() const override;
|
||||
void makeSectionCut(TopoDS_Shape &baseShape) override;
|
||||
TopoDS_Shape getShapeToIntersect() override;
|
||||
gp_Pln getSectionPlane() const override;
|
||||
TopoDS_Compound alignSectionFaces(TopoDS_Shape faceIntersections) override;
|
||||
std::pair<Base::Vector3d, Base::Vector3d>
|
||||
sectionLineEnds() override;
|
||||
|
||||
bool boxesIntersect(TopoDS_Face& face, TopoDS_Shape &shape);
|
||||
TopoDS_Shape shapeShapeIntersect(const TopoDS_Shape& shape0, const TopoDS_Shape& shape1);
|
||||
std::vector<TopoDS_Face> faceShapeIntersect(const TopoDS_Face& face, const TopoDS_Shape& shape);
|
||||
TopoDS_Shape extrudeWireToFace(TopoDS_Wire& wire, gp_Dir extrudeDir, double extrudeDist);
|
||||
TopoDS_Shape makeAlignedPieces(const TopoDS_Shape& rawShape,
|
||||
const TopoDS_Shape& toolFaceShape,
|
||||
double extrudeDistance);
|
||||
TopoDS_Shape distributeAlignedPieces(std::vector<TopoDS_Shape> pieces);
|
||||
TopoDS_Compound singleToolIntersections(const TopoDS_Shape& cutShape);
|
||||
TopoDS_Compound piecewiseToolIntersections(const TopoDS_Shape& cutShape);
|
||||
|
||||
BaseGeomPtrVector makeSectionLineGeometry();
|
||||
std::pair<Base::Vector3d, Base::Vector3d>
|
||||
sectionArrowDirs();
|
||||
TopoDS_Wire makeSectionLineWire();
|
||||
|
||||
TopoDS_Wire makeProfileWire(App::DocumentObject* toolObj);
|
||||
TopoDS_Wire makeNoseToTailWire(TopoDS_Wire inWire);
|
||||
gp_Dir projectProfileWire(TopoDS_Wire profileWire, gp_Ax3 paperCS);
|
||||
ChangePointVector getChangePointsFromSectionLine();
|
||||
|
||||
bool validateProfilePosition(TopoDS_Wire profileWire,
|
||||
gp_Ax2 sectionCS,
|
||||
gp_Dir& gClosestBasis) const;
|
||||
bool showSegment(gp_Dir segmentNormal) const;
|
||||
|
||||
static bool isProfileObject(App::DocumentObject* obj);
|
||||
static bool isMultiSegmentProfile(App::DocumentObject* obj);
|
||||
static bool isLinearProfile(App::DocumentObject* obj);
|
||||
|
||||
private:
|
||||
gp_Dir getFaceNormal(TopoDS_Face& face);
|
||||
|
||||
TopoDS_Shape m_toolFaceShape;
|
||||
TopoDS_Wire m_profileWire;
|
||||
|
||||
static const char* ProjectionStrategyEnums[];
|
||||
};
|
||||
|
||||
using DrawComplexSectionPython = App::FeaturePythonT<DrawComplexSection>;
|
||||
|
||||
} //namespace TechDraw
|
||||
|
||||
#endif
|
||||
|
||||
@@ -512,6 +512,12 @@ std::vector<TopoDS_Edge> DrawProjectSplit::scrubEdges(const std::vector<TechDraw
|
||||
std::vector<TopoDS_Edge> DrawProjectSplit::scrubEdges(std::vector<TopoDS_Edge>& origEdges,
|
||||
std::vector<TopoDS_Edge> &closedEdges)
|
||||
{
|
||||
if (origEdges.empty()) {
|
||||
//how did this happen? if Scale is zero, all the edges will be zero length,
|
||||
//but Scale property has constraint, so this shouldn't happen!
|
||||
// Base::Console().Message("DPS::scrubEdges(2) - origEdges is empty\n"); //debug
|
||||
return std::vector<TopoDS_Edge>();
|
||||
}
|
||||
//HLR usually delivers overlapping edges. We need to refine edge overlaps
|
||||
//into non-overlapping pieces
|
||||
std::vector<TopoDS_Edge> noOverlaps;
|
||||
|
||||
@@ -23,36 +23,38 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <cmath>
|
||||
# include <cstdlib>
|
||||
# include <cstring>
|
||||
# include <sstream>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
|
||||
# include <boost/regex.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
# include <QChar>
|
||||
# include <QPointF>
|
||||
# include <QString>
|
||||
#include <QChar>
|
||||
#include <QPointF>
|
||||
#include <QString>
|
||||
|
||||
# include <BRep_Builder.hxx>
|
||||
# include <BRep_Tool.hxx>
|
||||
# include <BRepAdaptor_Curve.hxx>
|
||||
# include <BRepAdaptor_Surface.hxx>
|
||||
# include <BRepExtrema_DistShapeShape.hxx>
|
||||
# include <BRepLProp_CLProps.hxx>
|
||||
# include <BRepLProp_CurveTool.hxx>
|
||||
# include <BRepLProp_SLProps.hxx>
|
||||
# include <BRepTools.hxx>
|
||||
# include <GCPnts_AbscissaPoint.hxx>
|
||||
# include <gp_Ax3.hxx>
|
||||
# include <gp_Dir.hxx>
|
||||
# include <gp_Elips.hxx>
|
||||
# include <gp_Pnt.hxx>
|
||||
# include <gp_Vec.hxx>
|
||||
# include <Precision.hxx>
|
||||
# include <TopExp.hxx>
|
||||
# include <TopExp_Explorer.hxx>
|
||||
# include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <BRepAdaptor_Surface.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <BRepExtrema_DistShapeShape.hxx>
|
||||
#include <BRepLProp_CLProps.hxx>
|
||||
#include <BRepLProp_CurveTool.hxx>
|
||||
#include <BRepLProp_SLProps.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <GCPnts_AbscissaPoint.hxx>
|
||||
#include <gp_Ax3.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Elips.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
@@ -511,6 +513,11 @@ Base::Vector3d DrawUtil::vecRotate(Base::Vector3d vec,
|
||||
return Base::Vector3d(xForm * (vec));
|
||||
}
|
||||
|
||||
gp_Vec DrawUtil::closestBasis(gp_Vec inVec)
|
||||
{
|
||||
return gp_Vec(togp_Dir(closestBasis(toVector3d(inVec))));
|
||||
}
|
||||
|
||||
Base::Vector3d DrawUtil::closestBasis(Base::Vector3d v)
|
||||
{
|
||||
Base::Vector3d result(0.0, -1, 0);
|
||||
@@ -522,11 +529,16 @@ Base::Vector3d DrawUtil::closestBasis(Base::Vector3d v)
|
||||
Base::Vector3d stdZr(0.0, 0.0, -1.0);
|
||||
|
||||
//first check if already a basis
|
||||
if (checkParallel(v, stdZ) ||
|
||||
checkParallel(v, stdY) ||
|
||||
checkParallel(v, stdX)) {
|
||||
if (v.Dot(stdX) == 1.0 ||
|
||||
v.Dot(stdY) == 1.0 ||
|
||||
v.Dot(stdZ) == 1.0) {
|
||||
return v;
|
||||
}
|
||||
if (v.Dot(stdX) == -1.0 ||
|
||||
v.Dot(stdY) == -1.0 ||
|
||||
v.Dot(stdZ) == -1.0) {
|
||||
return -v;
|
||||
}
|
||||
|
||||
//not a basis. find smallest angle with a basis.
|
||||
double angleX, angleY, angleZ, angleXr, angleYr, angleZr, angleMin;
|
||||
@@ -537,23 +549,139 @@ Base::Vector3d DrawUtil::closestBasis(Base::Vector3d v)
|
||||
angleYr = stdYr.GetAngle(v);
|
||||
angleZr = stdZr.GetAngle(v);
|
||||
|
||||
angleMin = angleX;
|
||||
if (angleY < angleMin) {
|
||||
return stdY;
|
||||
angleMin = std::min({angleX, angleY, angleZ, angleXr, angleYr, angleZr});
|
||||
if (angleX == angleMin) {
|
||||
return Base::Vector3d(1.0, 0.0, 0.0);
|
||||
}
|
||||
if (angleZ < angleMin) {
|
||||
return stdZ;
|
||||
|
||||
if (angleY == angleMin) {
|
||||
return Base::Vector3d(0.0, 1.0, 0.0);
|
||||
}
|
||||
if (angleXr < angleMin) {
|
||||
return stdXr;
|
||||
|
||||
if (angleZ == angleMin) {
|
||||
return Base::Vector3d(0.0, 0.0, 1.0);
|
||||
}
|
||||
if (angleYr < angleMin) {
|
||||
return stdYr;
|
||||
|
||||
if (angleXr == angleMin) {
|
||||
return Base::Vector3d(1.0, 0.0, 0.0);
|
||||
}
|
||||
if (angleZr < angleMin) {
|
||||
return stdZr;
|
||||
|
||||
if (angleYr == angleMin) {
|
||||
return Base::Vector3d(0.0, 1.0, 0.0);
|
||||
}
|
||||
return stdX;
|
||||
|
||||
if (angleZr == angleMin) {
|
||||
return Base::Vector3d(0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
//should not get to here
|
||||
return Base::Vector3d(1.0, 0.0, 0.0);
|
||||
|
||||
}
|
||||
|
||||
Base::Vector3d DrawUtil::closestBasis(Base::Vector3d vDir, gp_Ax2 coordSys)
|
||||
{
|
||||
gp_Dir gDir(vDir.x, vDir.y, vDir.z);
|
||||
return closestBasis(gDir, coordSys);
|
||||
}
|
||||
|
||||
Base::Vector3d DrawUtil::closestBasis(gp_Dir gDir, gp_Ax2 coordSys)
|
||||
{
|
||||
gp_Dir xCS = coordSys.XDirection(); //these are unit vectors?
|
||||
gp_Dir yCS = coordSys.YDirection();
|
||||
gp_Dir zCS = coordSys.Direction();
|
||||
|
||||
//first check if already a basis
|
||||
if (gDir.Dot(xCS) == 1.0 ||
|
||||
gDir.Dot(yCS) == 1.0 ||
|
||||
gDir.Dot(zCS) == 1.0 ) {
|
||||
//gDir is parallel with a basis
|
||||
return Base::Vector3d( gDir.X(), gDir.Y(), gDir.Z()) ;
|
||||
}
|
||||
|
||||
if (gDir.Dot(xCS.Reversed()) == 1.0 ||
|
||||
gDir.Dot(yCS.Reversed()) == 1.0 ||
|
||||
gDir.Dot(zCS.Reversed()) == 1.0 ) {
|
||||
//gDir is anti-parallel with a basis
|
||||
return Base::Vector3d( -gDir.X(), -gDir.Y(), -gDir.Z());
|
||||
}
|
||||
|
||||
//not a basis. find smallest angle with a basis.
|
||||
double angleX, angleY, angleZ, angleXr, angleYr, angleZr, angleMin;
|
||||
angleX = gDir.Angle(xCS);
|
||||
angleY = gDir.Angle(yCS);
|
||||
angleZ = gDir.Angle(zCS);
|
||||
angleXr = gDir.Angle(xCS.Reversed());
|
||||
angleYr = gDir.Angle(yCS.Reversed());
|
||||
angleZr = gDir.Angle(zCS.Reversed());
|
||||
|
||||
angleMin = std::min({angleX, angleY, angleZ, angleXr, angleYr, angleZr});
|
||||
if (angleX == angleMin) {
|
||||
return Base::Vector3d(xCS.X(), xCS.Y(), xCS.Z());
|
||||
}
|
||||
|
||||
if (angleY == angleMin) {
|
||||
return Base::Vector3d(yCS.X(), yCS.Y(), yCS.Z());
|
||||
}
|
||||
|
||||
if (angleZ == angleMin) {
|
||||
return Base::Vector3d(zCS.X(), zCS.Y(), zCS.Z()) ;
|
||||
}
|
||||
|
||||
if (angleXr == angleMin) {
|
||||
return Base::Vector3d(-xCS.X(), -xCS.Y(), -xCS.Z());
|
||||
}
|
||||
|
||||
if (angleYr == angleMin) {
|
||||
return Base::Vector3d(-yCS.X(), -yCS.Y(), -yCS.Z());
|
||||
}
|
||||
|
||||
if (angleZr == angleMin) {
|
||||
return Base::Vector3d(-zCS.X(), -zCS.Y(), -zCS.Z());
|
||||
}
|
||||
|
||||
//should not get to here
|
||||
return Base::Vector3d(xCS.X(), xCS.Y(), xCS.Z());
|
||||
}
|
||||
|
||||
double DrawUtil::getWidthInDirection(gp_Dir direction, TopoDS_Shape& shape)
|
||||
{
|
||||
Base::Vector3d stdX(1.0, 0.0, 0.0);
|
||||
Base::Vector3d stdY(0.0, 1.0, 0.0);
|
||||
Base::Vector3d stdZ(0.0, 0.0, 1.0);
|
||||
Base::Vector3d stdXr(-1.0, 0.0, 0.0);
|
||||
Base::Vector3d stdYr(0.0, -1.0, 0.0);
|
||||
Base::Vector3d stdZr(0.0, 0.0, -1.0);
|
||||
Base::Vector3d vClosestBasis = closestBasis(toVector3d(direction));
|
||||
|
||||
Bnd_Box shapeBox;
|
||||
shapeBox.SetGap(0.0);
|
||||
BRepBndLib::AddOptimal(shape, shapeBox);
|
||||
double xMin = 0, xMax = 0, yMin = 0, yMax = 0, zMin = 0, zMax = 0;
|
||||
if (shapeBox.IsVoid()) {
|
||||
//this really shouldn't happen here as null shapes should have been caught
|
||||
//long before this
|
||||
Base::Console().Error("DU::getWidthInDirection - shapeBox is void\n");
|
||||
return 0.0;
|
||||
}
|
||||
shapeBox.Get(xMin, yMin, zMin, xMax, yMax, zMax);
|
||||
|
||||
if (vClosestBasis.IsEqual(stdX, EWTOLERANCE) ||
|
||||
vClosestBasis.IsEqual(stdXr, EWTOLERANCE) ) {
|
||||
return xMax - xMin;
|
||||
}
|
||||
|
||||
if (vClosestBasis.IsEqual(stdY, EWTOLERANCE) ||
|
||||
vClosestBasis.IsEqual(stdYr, EWTOLERANCE) ) {
|
||||
return yMax - yMin;
|
||||
}
|
||||
|
||||
if (vClosestBasis.IsEqual(stdZ, EWTOLERANCE) ||
|
||||
vClosestBasis.IsEqual(stdZr, EWTOLERANCE) ) {
|
||||
return zMax - zMin;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//based on Function provided by Joe Dowsett, 2014
|
||||
@@ -873,6 +1001,102 @@ void DrawUtil::encodeXmlSpecialChars(std::string& inoutText)
|
||||
inoutText.swap(buffer);
|
||||
}
|
||||
|
||||
//Sort edges into nose to tail order. From Part/App/AppPartPy.cpp. gives back a sequence
|
||||
//of nose to tail edges and a shrunken input sequence of edges (the unconnected left overs)
|
||||
//struct EdgePoints {
|
||||
// gp_Pnt v1, v2;
|
||||
// std::list<TopoDS_Edge>::iterator it;
|
||||
// TopoDS_Edge edge;
|
||||
//};
|
||||
std::list<TopoDS_Edge> DrawUtil::sort_Edges(double tol3d, std::list<TopoDS_Edge>& edges)
|
||||
{
|
||||
tol3d = tol3d * tol3d;
|
||||
std::list<EdgePoints> edge_points;
|
||||
TopExp_Explorer xp;
|
||||
for (std::list<TopoDS_Edge>::iterator it = edges.begin(); it != edges.end(); ++it) {
|
||||
EdgePoints ep;
|
||||
xp.Init(*it,TopAbs_VERTEX);
|
||||
ep.v1 = BRep_Tool::Pnt(TopoDS::Vertex(xp.Current()));
|
||||
xp.Next();
|
||||
ep.v2 = BRep_Tool::Pnt(TopoDS::Vertex(xp.Current()));
|
||||
ep.it = it;
|
||||
ep.edge = *it;
|
||||
edge_points.push_back(ep);
|
||||
}
|
||||
|
||||
if (edge_points.empty())
|
||||
return std::list<TopoDS_Edge>();
|
||||
|
||||
std::list<TopoDS_Edge> sorted;
|
||||
gp_Pnt gpChainFirst, gpChainLast;
|
||||
gpChainFirst = edge_points.front().v1;
|
||||
gpChainLast = edge_points.front().v2;
|
||||
|
||||
sorted.push_back(edge_points.front().edge);
|
||||
edges.erase(edge_points.front().it);
|
||||
edge_points.erase(edge_points.begin());
|
||||
|
||||
while (!edge_points.empty()) {
|
||||
// search for adjacent edge
|
||||
std::list<EdgePoints>::iterator itEdgePoint;
|
||||
for (itEdgePoint = edge_points.begin(); itEdgePoint != edge_points.end(); ++itEdgePoint) {
|
||||
if (itEdgePoint->v1.SquareDistance(gpChainLast) <= tol3d) {
|
||||
//found a connection from end of chain to start of edge
|
||||
gpChainLast = itEdgePoint->v2;
|
||||
sorted.push_back(itEdgePoint->edge);
|
||||
edges.erase(itEdgePoint->it);
|
||||
edge_points.erase(itEdgePoint);
|
||||
itEdgePoint = edge_points.begin();
|
||||
break;
|
||||
}
|
||||
else if (itEdgePoint->v2.SquareDistance(gpChainFirst) <= tol3d) {
|
||||
//found a connection from start of chain to end of edge
|
||||
gpChainFirst = itEdgePoint->v1;
|
||||
sorted.push_front(itEdgePoint->edge);
|
||||
edges.erase(itEdgePoint->it);
|
||||
edge_points.erase(itEdgePoint);
|
||||
itEdgePoint = edge_points.begin();
|
||||
break;
|
||||
}
|
||||
else if (itEdgePoint->v2.SquareDistance(gpChainLast) <= tol3d) {
|
||||
//found a connection from end of chain to end of edge
|
||||
gpChainLast = itEdgePoint->v1;
|
||||
Standard_Real firstParam, lastParam;
|
||||
const Handle(Geom_Curve) & curve = BRep_Tool::Curve(itEdgePoint->edge, firstParam, lastParam);
|
||||
firstParam = curve->ReversedParameter(firstParam);
|
||||
lastParam = curve->ReversedParameter(lastParam);
|
||||
TopoDS_Edge edgeReversed = BRepBuilderAPI_MakeEdge(curve->Reversed(), firstParam, lastParam);
|
||||
sorted.push_back(edgeReversed);
|
||||
edges.erase(itEdgePoint->it);
|
||||
edge_points.erase(itEdgePoint);
|
||||
itEdgePoint = edge_points.begin();
|
||||
break;
|
||||
}
|
||||
else if (itEdgePoint->v1.SquareDistance(gpChainFirst) <= tol3d) {
|
||||
//found a connection from start of chain to start of edge
|
||||
gpChainFirst = itEdgePoint->v2;
|
||||
Standard_Real firstParam, lastParam;
|
||||
const Handle(Geom_Curve) & curve = BRep_Tool::Curve(itEdgePoint->edge, firstParam, lastParam);
|
||||
firstParam = curve->ReversedParameter(firstParam);
|
||||
lastParam = curve->ReversedParameter(lastParam);
|
||||
TopoDS_Edge edgeReversed = BRepBuilderAPI_MakeEdge(curve->Reversed(), firstParam, lastParam);
|
||||
sorted.push_front(edgeReversed);
|
||||
edges.erase(itEdgePoint->it);
|
||||
edge_points.erase(itEdgePoint);
|
||||
itEdgePoint = edge_points.begin();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((itEdgePoint == edge_points.end()) || (gpChainLast.SquareDistance(gpChainFirst) <= tol3d)) {
|
||||
// no adjacent edge found or polyline is closed
|
||||
return sorted;
|
||||
}
|
||||
}
|
||||
|
||||
return sorted;
|
||||
}
|
||||
|
||||
// Supplementary mathematical functions
|
||||
// ====================================
|
||||
|
||||
@@ -1367,7 +1591,7 @@ void DrawUtil::dumpCS3(const char* text,
|
||||
gp_Dir baseX = CS.XDirection();
|
||||
gp_Dir baseY = CS.YDirection();
|
||||
gp_Pnt baseOrg = CS.Location();
|
||||
Base::Console().Message("DU::dumpCSF - %s Loc: %s Axis: %s X: %s Y: %s\n", text,
|
||||
Base::Console().Message("DU::dumpCS3 - %s Loc: %s Axis: %s X: %s Y: %s\n", text,
|
||||
DrawUtil::formatVector(baseOrg).c_str(),
|
||||
DrawUtil::formatVector(baseAxis).c_str(),
|
||||
DrawUtil::formatVector(baseX).c_str(),
|
||||
|
||||
@@ -70,6 +70,13 @@
|
||||
namespace TechDraw
|
||||
{
|
||||
|
||||
//used by sort_Edges
|
||||
struct EdgePoints {
|
||||
gp_Pnt v1, v2;
|
||||
std::list<TopoDS_Edge>::iterator it;
|
||||
TopoDS_Edge edge;
|
||||
};
|
||||
|
||||
/// Convenient utility functions for TechDraw Module
|
||||
class TechDrawExport DrawUtil {
|
||||
public:
|
||||
@@ -122,10 +129,15 @@ class TechDrawExport DrawUtil {
|
||||
double angle,
|
||||
Base::Vector3d axis,
|
||||
Base::Vector3d org = Base::Vector3d(0.0, 0.0, 0.0));
|
||||
|
||||
static Base::Vector3d closestBasis(Base::Vector3d v);
|
||||
static gp_Vec closestBasis(gp_Vec inVec);
|
||||
static Base::Vector3d closestBasis(Base::Vector3d vDir, gp_Ax2 coordSys);
|
||||
static Base::Vector3d closestBasis(gp_Dir gDir, gp_Ax2 coordSys);
|
||||
|
||||
static double getWidthInDirection(gp_Dir direction, TopoDS_Shape& shape);
|
||||
|
||||
static double getDefaultLineWeight(std::string s);
|
||||
/* static Base::Vector3d vector23(const Base::Vector3d& v2) { return Base::Vector3d(v2.x, v2.y, 0.0); }*/
|
||||
/* static Base::Vector3d vector32(const Base::Vector3d& v3) { return Base::Vector3d(v3.x, v3.y); }*/
|
||||
//! is pt between end1 and end2?
|
||||
static bool isBetween(const Base::Vector3d pt, const Base::Vector3d end1, const Base::Vector3d end2);
|
||||
//! find intersection in 2d for 2 lines in point+direction form
|
||||
@@ -133,8 +145,10 @@ class TechDrawExport DrawUtil {
|
||||
Base::Vector3d p2, Base::Vector3d d2);
|
||||
static Base::Vector2d Intersect2d(Base::Vector2d p1, Base::Vector2d d1,
|
||||
Base::Vector2d p2, Base::Vector2d d2);
|
||||
static Base::Vector3d gpPnt2V3(const gp_Pnt gp) { return Base::Vector3d(gp.X(), gp.Y(), gp.Z()); }
|
||||
static gp_Pnt V32gpPnt(const Base::Vector3d v) { return gp_Pnt(v.x, v.y, v.z); }
|
||||
static Base::Vector3d toVector3d(const gp_Pnt gp) { return Base::Vector3d(gp.X(), gp.Y(), gp.Z()); }
|
||||
static Base::Vector3d toVector3d(const gp_Dir gp) { return Base::Vector3d(gp.X(), gp.Y(), gp.Z()); }
|
||||
static gp_Pnt togp_Pnt(const Base::Vector3d v) { return gp_Pnt(v.x, v.y, v.z); }
|
||||
static gp_Dir togp_Dir(const Base::Vector3d v) { return gp_Dir(v.x, v.y, v.z); }
|
||||
static std::string shapeToString(TopoDS_Shape s);
|
||||
static TopoDS_Shape shapeFromString(std::string s);
|
||||
static Base::Vector3d invertY(Base::Vector3d v);
|
||||
@@ -148,7 +162,7 @@ class TechDrawExport DrawUtil {
|
||||
static bool circulation(Base::Vector3d A, Base::Vector3d B, Base::Vector3d C);
|
||||
static int countSubShapes(TopoDS_Shape shape, TopAbs_ShapeEnum subShape);
|
||||
static void encodeXmlSpecialChars(std::string& inoutText);
|
||||
|
||||
static std::list<TopoDS_Edge> sort_Edges(double tol3d, std::list<TopoDS_Edge>& edges);
|
||||
|
||||
// Supplementary mathematical functions
|
||||
static int sgn(double x);
|
||||
|
||||
@@ -118,6 +118,15 @@ void DrawView::onChanged(const App::Property* prop)
|
||||
//Coding note: calling execute, recompute or recomputeFeature inside an onChanged
|
||||
//method can create infinite loops if the called method changes a property. In general
|
||||
//don't do this! There are situations where it is OK, but careful analysis is a must.
|
||||
|
||||
if (prop == &Scale &&
|
||||
Scale.getValue() < Precision::Confusion()) {
|
||||
//this is not supposed to happen since Scale has constraints, but it may
|
||||
//happen during changes made in PropertyEditor?
|
||||
Scale.setValue(1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isRestoring()) {
|
||||
App::DocumentObject::onChanged(prop);
|
||||
return;
|
||||
|
||||
@@ -25,29 +25,30 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
# include <QtConcurrentRun>
|
||||
# include <Bnd_Box.hxx>
|
||||
# include <BRep_Tool.hxx>
|
||||
# include <BRepAlgo_NormalProjection.hxx>
|
||||
# include <BRepBndLib.hxx>
|
||||
# include <BRepBuilderAPI_Copy.hxx>
|
||||
# include <BRepBuilderAPI_MakeFace.hxx>
|
||||
# include <BRepBuilderAPI_MakeWire.hxx>
|
||||
# include <BRepTools.hxx>
|
||||
# include <gp_Ax2.hxx>
|
||||
# include <gp_Dir.hxx>
|
||||
# include <gp_Pln.hxx>
|
||||
# include <gp_Pnt.hxx>
|
||||
# include <HLRAlgo_Projector.hxx>
|
||||
# include <ShapeAnalysis.hxx>
|
||||
# include <TopExp.hxx>
|
||||
# include <TopoDS.hxx>
|
||||
# include <TopoDS_Edge.hxx>
|
||||
# include <TopoDS_Face.hxx>
|
||||
# include <TopoDS_Shape.hxx>
|
||||
# include <TopoDS_Vertex.hxx>
|
||||
# include <TopoDS_Wire.hxx>
|
||||
#include <sstream>
|
||||
#include <QtConcurrentRun>
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepAlgo_NormalProjection.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
#include <BRepBuilderAPI_Copy.hxx>
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
#include <BRepBuilderAPI_MakeWire.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <HLRAlgo_Projector.hxx>
|
||||
#include <ShapeAnalysis.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
@@ -237,7 +238,7 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void)
|
||||
|
||||
TopoDS_Shape shape = getSourceShape();
|
||||
if (shape.IsNull()) {
|
||||
Base::Console().Log("DVP::execute - %s - Source shape is Null.\n",
|
||||
Base::Console().Message("DVP::execute - %s - Source shape is Null.\n",
|
||||
getNameInDocument());
|
||||
return DrawView::execute();
|
||||
}
|
||||
@@ -345,7 +346,7 @@ GeometryObject* DrawViewPart::makeGeometryForShape(TopoDS_Shape& shape)
|
||||
}
|
||||
|
||||
//create a geometry object and trigger the HLR process in another thread
|
||||
TechDraw::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape& shape, gp_Ax2& viewAxis)
|
||||
TechDraw::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape& shape, const gp_Ax2 &viewAxis)
|
||||
{
|
||||
// Base::Console().Message("DVP::buildGeometryObject() - %s\n", getNameInDocument());
|
||||
showProgressMessage(getNameInDocument(), "is finding hidden lines");
|
||||
@@ -468,7 +469,7 @@ void DrawViewPart::extractFaces()
|
||||
geometryObject->getVisibleFaceEdges(SmoothVisible.getValue(),SeamVisible.getValue());
|
||||
|
||||
if (goEdges.empty()) {
|
||||
Base::Console().Message("DVP::extractFaces - %s - no face edges available!\n", getNameInDocument());
|
||||
// Base::Console().Message("DVP::extractFaces - %s - no face edges available!\n", getNameInDocument()); //debug
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -476,6 +477,13 @@ void DrawViewPart::extractFaces()
|
||||
std::vector<TopoDS_Edge> closedEdges;
|
||||
std::vector<TopoDS_Edge> cleanEdges = DrawProjectSplit::scrubEdges(goEdges, closedEdges);
|
||||
|
||||
if (cleanEdges.empty() &&
|
||||
closedEdges.empty()) {
|
||||
//how does this happen? something wrong somewhere
|
||||
// Base::Console().Message("DVP::extractFaces - no clean or closed wires\n"); //debug
|
||||
return;
|
||||
}
|
||||
|
||||
//use EdgeWalker to make wires from edges
|
||||
EdgeWalker eWalker;
|
||||
std::vector<TopoDS_Wire> sortedWires;
|
||||
@@ -892,8 +900,27 @@ BaseGeomPtr DrawViewPart::projectEdge(const TopoDS_Edge& e) const
|
||||
projector.Add(e);
|
||||
projector.Build();
|
||||
TopoDS_Shape s = projector.Projection();
|
||||
// Base::Console().Message("DVP::projectEdge - s.IsNull: %d\n", s.IsNull());
|
||||
BaseGeomPtr result;
|
||||
return BaseGeom::baseFactory(TopoDS::Edge(s));
|
||||
}
|
||||
|
||||
//simple projection of inWire with conversion of the result to TD geometry
|
||||
BaseGeomPtrVector DrawViewPart::projectWire(const TopoDS_Wire& inWire) const
|
||||
{
|
||||
// Base::Console().Message("DVP::projectWire() - inWire.IsNull: %d\n", inWire.IsNull());
|
||||
BaseGeomPtrVector result;
|
||||
Base::Vector3d stdOrg(0.0, 0.0, 0.0);
|
||||
|
||||
TopoDS_Face paper = BRepBuilderAPI_MakeFace(gp_Pln(getProjectionCS(stdOrg)));
|
||||
BRepAlgo_NormalProjection projector(paper);
|
||||
projector.Add(inWire);
|
||||
projector.Build();
|
||||
BRepTools::Write(projector.Projection(), "DVPprojectedWire.brep"); //debug
|
||||
|
||||
TopExp_Explorer expShape(projector.Projection(), TopAbs_EDGE);
|
||||
for (; expShape.More(); expShape.Next()) {
|
||||
BaseGeomPtr edge = BaseGeom::baseFactory(TopoDS::Edge(expShape.Current()));
|
||||
result.push_back(edge);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -142,11 +142,12 @@ public:
|
||||
virtual Base::Vector3d projectPoint(const Base::Vector3d& pt,
|
||||
bool invert = true) const;
|
||||
virtual BaseGeomPtr projectEdge(const TopoDS_Edge& e) const;
|
||||
virtual BaseGeomPtrVector projectWire(const TopoDS_Wire& inWire) const;
|
||||
|
||||
virtual gp_Ax2 getViewAxis(const Base::Vector3d& pt,
|
||||
const Base::Vector3d& direction,
|
||||
const bool flip=true) const;
|
||||
virtual gp_Ax2 getProjectionCS(Base::Vector3d pt) const;
|
||||
virtual gp_Ax2 getProjectionCS(Base::Vector3d pt = Base::Vector3d(0.0, 0.0, 0.0)) const;
|
||||
virtual Base::Vector3d getXDirection() const; //don't use XDirection.getValue()
|
||||
virtual Base::Vector3d getOriginalCentroid() const;
|
||||
virtual Base::Vector3d getCurrentCentroid() const;
|
||||
@@ -223,7 +224,7 @@ protected:
|
||||
void onChanged(const App::Property* prop) override;
|
||||
void unsetupObject() override;
|
||||
|
||||
virtual TechDraw::GeometryObject* buildGeometryObject(TopoDS_Shape& shape, gp_Ax2& viewAxis);
|
||||
virtual TechDraw::GeometryObject* buildGeometryObject(TopoDS_Shape& shape, const gp_Ax2& viewAxis);
|
||||
virtual TechDraw::GeometryObject* makeGeometryForShape(TopoDS_Shape& shape); //const??
|
||||
void partExec(TopoDS_Shape& shape);
|
||||
virtual void addShapes2d(void);
|
||||
|
||||
@@ -22,33 +22,55 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
//DrawViewSection processing overview
|
||||
|
||||
//execute
|
||||
// sectionExec(getShapeToCut())
|
||||
|
||||
//sectionExec
|
||||
// makeSectionCut(baseShape)
|
||||
|
||||
//makeSectionCut (separate thread)
|
||||
// m_cuttingTool = makeCuttingTool (DVSTool.brep)
|
||||
// m_cutPieces = (baseShape - m_cuttingTool) (DVSCutPieces.brep)
|
||||
|
||||
//onSectionCutFinished
|
||||
// m_preparedShape = prepareShape(m_cutPieces) - centered, scaled, rotated
|
||||
// geometryObject = DVP::buildGeometryObject(m_preparedShape) (HLR)
|
||||
|
||||
//postHlrTasks
|
||||
// faceIntersections = findSectionPlaneIntersections
|
||||
// m_sectionTopoDSFaces = alignSectionFaces(faceIntersections)
|
||||
// m_tdSectionFaces = makeTDSectionFaces(m_sectionTopoDSFaces)
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <chrono>
|
||||
# include <sstream>
|
||||
# include <QtConcurrentRun>
|
||||
# include <Bnd_Box.hxx>
|
||||
# include <BRep_Builder.hxx>
|
||||
# include <BRepBndLib.hxx>
|
||||
# include <BRepAdaptor_Surface.hxx>
|
||||
# include <BRepAlgoAPI_Cut.hxx>
|
||||
# include <BRepBuilderAPI_Copy.hxx>
|
||||
# include <BRepBuilderAPI_MakeFace.hxx>
|
||||
# include <BRepBuilderAPI_Transform.hxx>
|
||||
# include <BRepPrimAPI_MakePrism.hxx>
|
||||
# include <BRepTools.hxx>
|
||||
# include <gp_Ax2.hxx>
|
||||
# include <gp_Ax3.hxx>
|
||||
# include <gp_Dir.hxx>
|
||||
# include <gp_Pln.hxx>
|
||||
# include <gp_Pnt.hxx>
|
||||
# include <TopoDS_Shape.hxx>
|
||||
# include <TopoDS.hxx>
|
||||
# include <TopoDS_Face.hxx>
|
||||
# include <TopoDS_Edge.hxx>
|
||||
# include <TopoDS_Compound.hxx>
|
||||
# include <TopExp_Explorer.hxx>
|
||||
#include <chrono>
|
||||
#include <sstream>
|
||||
#include <QtConcurrentRun>
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
#include <BRepAdaptor_Surface.hxx>
|
||||
#include <BRepAlgoAPI_Cut.hxx>
|
||||
#include <BRepBuilderAPI_Copy.hxx>
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
#include <BRepBuilderAPI_Transform.hxx>
|
||||
#include <BRepPrimAPI_MakePrism.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Ax3.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
@@ -58,21 +80,32 @@
|
||||
#include <Base/FileInfo.h>
|
||||
#include <Base/Parameter.h>
|
||||
|
||||
#include "DrawViewSection.h"
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
||||
#include "DrawGeomHatch.h"
|
||||
#include "DrawHatch.h"
|
||||
#include "DrawProjGroupItem.h"
|
||||
#include "DrawProjGroupItem.h"
|
||||
#include "DrawUtil.h"
|
||||
#include "DrawUtil.h"
|
||||
#include "EdgeWalker.h"
|
||||
#include "Geometry.h"
|
||||
#include "Geometry.h"
|
||||
#include "GeometryObject.h"
|
||||
#include "GeometryObject.h"
|
||||
#include "HatchLine.h"
|
||||
|
||||
#include "DrawViewSection.h"
|
||||
|
||||
using namespace TechDraw;
|
||||
|
||||
using DU = DrawUtil;
|
||||
|
||||
const char* DrawViewSection::SectionDirEnums[]= {"Right",
|
||||
"Left",
|
||||
"Up",
|
||||
"Down",
|
||||
"Aligned",
|
||||
nullptr};
|
||||
|
||||
const char* DrawViewSection::CutSurfaceEnums[]= {"Hide",
|
||||
@@ -88,7 +121,8 @@ const char* DrawViewSection::CutSurfaceEnums[]= {"Hide",
|
||||
PROPERTY_SOURCE(TechDraw::DrawViewSection, TechDraw::DrawViewPart)
|
||||
|
||||
DrawViewSection::DrawViewSection() :
|
||||
m_waitingForCut(false)
|
||||
m_waitingForCut(false),
|
||||
m_shapeSize(0.0)
|
||||
{
|
||||
static const char *sgroup = "Section";
|
||||
static const char *fgroup = "Cut Surface Format";
|
||||
@@ -200,29 +234,37 @@ void DrawViewSection::onChanged(const App::Property* prop)
|
||||
DrawView::onChanged(prop);
|
||||
}
|
||||
|
||||
TopoDS_Shape DrawViewSection::getShapeToCut()
|
||||
{
|
||||
// Base::Console().Message("DVS::getShapeToCut()\n");
|
||||
App::DocumentObject* base = BaseView.getValue();
|
||||
TechDraw::DrawViewPart* dvp = nullptr;
|
||||
if (!base ||
|
||||
!base->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
|
||||
//this can probably only happen with scripting
|
||||
return TopoDS_Shape();
|
||||
} else {
|
||||
dvp = static_cast<TechDraw::DrawViewPart*>(base);
|
||||
}
|
||||
TopoDS_Shape shapeToCut = dvp->getSourceShape();
|
||||
if (FuseBeforeCut.getValue()) {
|
||||
shapeToCut = dvp->getSourceShapeFused();
|
||||
}
|
||||
return shapeToCut;
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn *DrawViewSection::execute()
|
||||
{
|
||||
// Base::Console().Message("DVS::execute() - %s\n", getNameInDocument());
|
||||
if (!keepUpdated()) {
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
App::DocumentObject* base = BaseView.getValue();
|
||||
if (!base) {
|
||||
if (!isBaseValid()) {
|
||||
return new App::DocumentObjectExecReturn("BaseView object not found");
|
||||
}
|
||||
|
||||
TechDraw::DrawViewPart* dvp = nullptr;
|
||||
if (!base->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
|
||||
//this can probably only happen with scripting
|
||||
return new App::DocumentObjectExecReturn("BaseView object is not a DrawViewPart object");
|
||||
} else {
|
||||
dvp = static_cast<TechDraw::DrawViewPart*>(base);
|
||||
}
|
||||
|
||||
TopoDS_Shape baseShape = dvp->getSourceShape();
|
||||
if (FuseBeforeCut.getValue()) {
|
||||
baseShape = dvp->getSourceShapeFused();
|
||||
}
|
||||
TopoDS_Shape baseShape = getShapeToCut();
|
||||
|
||||
if (baseShape.IsNull()) {
|
||||
return DrawView::execute();
|
||||
@@ -230,7 +272,6 @@ App::DocumentObjectExecReturn *DrawViewSection::execute()
|
||||
|
||||
m_saveShape = baseShape; //save shape for 2nd pass
|
||||
|
||||
// checkXDirection();
|
||||
bool haveX = checkXDirection();
|
||||
if (!haveX) {
|
||||
//block touch/onChanged stuff
|
||||
@@ -246,6 +287,16 @@ App::DocumentObjectExecReturn *DrawViewSection::execute()
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
bool DrawViewSection::isBaseValid() const
|
||||
{
|
||||
App::DocumentObject* base = BaseView.getValue();
|
||||
if (base &&
|
||||
base->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DrawViewSection::sectionExec(TopoDS_Shape& baseShape)
|
||||
{
|
||||
// Base::Console().Message("DVS::sectionExec() - %s baseShape.IsNull: %d\n",
|
||||
@@ -289,112 +340,128 @@ void DrawViewSection::makeSectionCut(TopoDS_Shape &baseShape)
|
||||
Bnd_Box centerBox;
|
||||
BRepBndLib::AddOptimal(baseShape, centerBox);
|
||||
centerBox.SetGap(0.0);
|
||||
gp_Pln pln = getSectionPlane();
|
||||
gp_Dir gpNormal = pln.Axis().Direction();
|
||||
Base::Vector3d orgPnt = SectionOrigin.getValue();
|
||||
|
||||
if(!isReallyInBox(gp_Pnt(orgPnt.x, orgPnt.y, orgPnt.z), centerBox)) {
|
||||
Base::Console().Warning("DVS: SectionOrigin doesn't intersect part in %s\n", getNameInDocument());
|
||||
}
|
||||
|
||||
// make cutting tool
|
||||
// Make the extrusion face
|
||||
double dMax = sqrt(centerBox.SquareExtent());
|
||||
BRepBuilderAPI_MakeFace mkFace(pln, -dMax, dMax, -dMax, dMax);
|
||||
TopoDS_Face aProjFace = mkFace.Face();
|
||||
if(aProjFace.IsNull()) {
|
||||
Base::Console().Warning("DVS: Section face is NULL in %s\n", getNameInDocument());
|
||||
return;
|
||||
}
|
||||
gp_Vec extrudeDir = dMax * gp_Vec(gpNormal);
|
||||
TopoDS_Shape prism = BRepPrimAPI_MakePrism(aProjFace, extrudeDir, false, true).Shape();
|
||||
m_shapeSize = sqrt(centerBox.SquareExtent());
|
||||
|
||||
// We need to copy the shape to not modify the BRepstructure
|
||||
BRepBuilderAPI_Copy BuilderCopy(baseShape);
|
||||
TopoDS_Shape myShape = BuilderCopy.Shape();
|
||||
m_saveShape = myShape; //save shape for 2nd pass
|
||||
|
||||
if (debugSection()) {
|
||||
BRepTools::Write(myShape, "DVSCopy.brep"); //debug
|
||||
}
|
||||
|
||||
m_cuttingTool = makeCuttingTool(m_shapeSize);
|
||||
|
||||
if (debugSection()) {
|
||||
BRepTools::Write(m_cuttingTool, "DVSTool.brep"); //debug
|
||||
}
|
||||
|
||||
// perform cut
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound pieces;
|
||||
builder.MakeCompound(pieces);
|
||||
TopoDS_Compound cutPieces;
|
||||
builder.MakeCompound(cutPieces);
|
||||
TopExp_Explorer expl(myShape, TopAbs_SOLID);
|
||||
int indb = 0;
|
||||
int outdb = 0;
|
||||
for (; expl.More(); expl.Next()) {
|
||||
indb++;
|
||||
const TopoDS_Solid& s = TopoDS::Solid(expl.Current());
|
||||
BRepAlgoAPI_Cut mkCut(s, prism);
|
||||
BRepAlgoAPI_Cut mkCut(s, m_cuttingTool);
|
||||
if (!mkCut.IsDone()) {
|
||||
Base::Console().Warning("DVS: Section cut has failed in %s\n", getNameInDocument());
|
||||
continue;
|
||||
}
|
||||
TopoDS_Shape cut = mkCut.Shape();
|
||||
builder.Add(pieces, cut);
|
||||
outdb++;
|
||||
builder.Add(cutPieces, mkCut.Shape());
|
||||
}
|
||||
|
||||
// pieces contains result of cutting each subshape in baseShape with tool
|
||||
TopoDS_Shape rawShape = pieces;
|
||||
// cutPieces contains result of cutting each subshape in baseShape with tool
|
||||
m_cutPieces = cutPieces;
|
||||
|
||||
if (debugSection()) {
|
||||
BRepTools::Write(myShape, "DVSCopy.brep"); //debug
|
||||
BRepTools::Write(aProjFace, "DVSFace.brep"); //debug
|
||||
BRepTools::Write(prism, "DVSTool.brep"); //debug
|
||||
BRepTools::Write(pieces, "DVSPieces.brep"); //debug
|
||||
BRepTools::Write(cutPieces, "DVSCutPieces.brep"); //debug
|
||||
}
|
||||
|
||||
// check for error in cut
|
||||
Bnd_Box testBox;
|
||||
BRepBndLib::AddOptimal(rawShape, testBox);
|
||||
BRepBndLib::AddOptimal(m_cutPieces, testBox);
|
||||
testBox.SetGap(0.0);
|
||||
if (testBox.IsVoid()) { //prism & input don't intersect. rawShape is garbage, don't bother.
|
||||
Base::Console().Warning("DVS::makeSectionCut - prism & input don't intersect - %s\n", Label.getValue());
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// build display geometry as in DVP, with minor mods
|
||||
TopoDS_Shape centeredShape;
|
||||
if (debugSection()) {
|
||||
BRepTools::Write(m_cutPieces, "DVSRawShapeAfter.brep"); //debug
|
||||
}
|
||||
|
||||
waitingForCut(false);
|
||||
}
|
||||
|
||||
//position, scale and rotate shape for buildGeometryObject
|
||||
TopoDS_Shape DrawViewSection::prepareShape(const TopoDS_Shape& rawShape,
|
||||
double shapeSize)
|
||||
{
|
||||
// Base::Console().Message("DVS::prepareShape - %s - rawShape.IsNull: %d shapeSize: %.3f\n",
|
||||
// getNameInDocument(), rawShape.IsNull(), shapeSize);
|
||||
(void) shapeSize; //shapeSize is not used in this base class, but is interesting for
|
||||
//derived classes
|
||||
// build display geometry as in DVP, with minor mods
|
||||
TopoDS_Shape preparedShape;
|
||||
try {
|
||||
Base::Vector3d origin(0.0, 0.0, 0.0);
|
||||
m_viewAxis = getProjectionCS(origin);
|
||||
m_projectionCS = getProjectionCS(origin);
|
||||
gp_Pnt inputCenter;
|
||||
inputCenter = TechDraw::findCentroid(rawShape,
|
||||
m_viewAxis);
|
||||
m_projectionCS);
|
||||
Base::Vector3d centroid(inputCenter.X(),
|
||||
inputCenter.Y(),
|
||||
inputCenter.Z());
|
||||
|
||||
centeredShape = TechDraw::moveShape(rawShape,
|
||||
preparedShape = TechDraw::moveShape(rawShape,
|
||||
centroid * -1.0);
|
||||
m_cutShape = centeredShape;
|
||||
m_cutShape = preparedShape;
|
||||
m_saveCentroid = centroid;
|
||||
|
||||
m_scaledShape = TechDraw::scaleShape(centeredShape,
|
||||
getScale());
|
||||
preparedShape = TechDraw::scaleShape(preparedShape,
|
||||
getScale());
|
||||
|
||||
if (!DrawUtil::fpCompare(Rotation.getValue(), 0.0)) {
|
||||
m_scaledShape = TechDraw::rotateShape(m_scaledShape,
|
||||
m_viewAxis,
|
||||
preparedShape = TechDraw::rotateShape(preparedShape,
|
||||
m_projectionCS,
|
||||
Rotation.getValue());
|
||||
}
|
||||
if (debugSection()) {
|
||||
BRepTools::Write(m_cutShape, "DVSmCutShape.brep"); //debug
|
||||
BRepTools::Write(m_scaledShape, "DVSScaled.brep"); //debug
|
||||
// DrawUtil::dumpCS("DVS::makeSectionCut - CS to GO", viewAxis);
|
||||
}
|
||||
|
||||
m_rawShape = rawShape; //save for section face finding
|
||||
|
||||
}
|
||||
catch (Standard_Failure& e1) {
|
||||
Base::Console().Warning("DVS::makeSectionCut - failed to build base shape %s - %s **\n",
|
||||
Base::Console().Warning("DVS::prepareShape - failed to build shape %s - %s **\n",
|
||||
getNameInDocument(), e1.GetMessageString());
|
||||
return;
|
||||
}
|
||||
return preparedShape;
|
||||
}
|
||||
|
||||
waitingForCut(false);
|
||||
TopoDS_Shape DrawViewSection::makeCuttingTool(double shapeSize)
|
||||
{
|
||||
// Base::Console().Message("DVS::makeCuttingTool(%.3f) - %s\n", shapeSize, getNameInDocument());
|
||||
// Make the extrusion face
|
||||
gp_Pln pln = getSectionPlane();
|
||||
gp_Dir gpNormal = pln.Axis().Direction();
|
||||
BRepBuilderAPI_MakeFace mkFace(pln, -shapeSize, shapeSize, -shapeSize, shapeSize);
|
||||
TopoDS_Face aProjFace = mkFace.Face();
|
||||
if(aProjFace.IsNull()) {
|
||||
return TopoDS_Shape();
|
||||
}
|
||||
if (debugSection()){
|
||||
BRepTools::Write(aProjFace, "DVSSectionFace.brep"); //debug
|
||||
}
|
||||
gp_Vec extrudeDir = shapeSize * gp_Vec(gpNormal);
|
||||
return BRepPrimAPI_MakePrism(aProjFace, extrudeDir, false, true).Shape();
|
||||
}
|
||||
|
||||
void DrawViewSection::onSectionCutFinished()
|
||||
@@ -404,10 +471,15 @@ void DrawViewSection::onSectionCutFinished()
|
||||
|
||||
showProgressMessage(getNameInDocument(), "has finished making section cut");
|
||||
|
||||
m_preparedShape = prepareShape(getShapeToPrepare(), m_shapeSize);
|
||||
if (debugSection()) {
|
||||
BRepTools::Write(m_preparedShape, "DVSPreparedShape.brep"); //debug
|
||||
}
|
||||
|
||||
postSectionCutTasks();
|
||||
|
||||
//display geometry for cut shape is in geometryObject as in DVP
|
||||
m_tempGeometryObject = buildGeometryObject(m_scaledShape, m_viewAxis);
|
||||
m_tempGeometryObject = buildGeometryObject(m_preparedShape, getSectionCS());
|
||||
}
|
||||
|
||||
//activities that depend on updated geometry object
|
||||
@@ -430,78 +502,44 @@ void DrawViewSection::postHlrTasks(void)
|
||||
|
||||
|
||||
// build section face geometry
|
||||
TopoDS_Compound faceIntersections = findSectionPlaneIntersections(m_rawShape);
|
||||
TopoDS_Compound faceIntersections = findSectionPlaneIntersections(getShapeToIntersect());
|
||||
if (faceIntersections.IsNull()) {
|
||||
requestPaint();
|
||||
return;
|
||||
}
|
||||
|
||||
TopoDS_Shape centeredShapeF = TechDraw::moveShape(faceIntersections,
|
||||
TopoDS_Shape centeredFaces = TechDraw::moveShape(faceIntersections,
|
||||
m_saveCentroid * -1.0);
|
||||
|
||||
TopoDS_Shape scaledSection = TechDraw::scaleShape(centeredShapeF,
|
||||
TopoDS_Shape scaledSection = TechDraw::scaleShape(centeredFaces,
|
||||
getScale());
|
||||
if (!DrawUtil::fpCompare(Rotation.getValue(), 0.0)) {
|
||||
scaledSection = TechDraw::rotateShape(scaledSection,
|
||||
m_viewAxis,
|
||||
getProjectionCS(),
|
||||
Rotation.getValue());
|
||||
}
|
||||
if (debugSection()) {
|
||||
BRepTools::Write(scaledSection, "DVSScaledFaces.brep"); //debug
|
||||
BRepTools::Write(faceIntersections, "DVSFaceIntersections.brep"); //debug
|
||||
}
|
||||
|
||||
// scaledSection is compound of TopoDS_Face intersections, but aligned to pln(origin, sectionNormal)
|
||||
// needs to be aligned to pln (origin, stdZ);
|
||||
gp_Ax3 R3;
|
||||
gp_Ax2 projCS = getSectionCS();
|
||||
gp_Ax3 proj3 = gp_Ax3(gp_Pnt(0.0, 0.0, 0.0),
|
||||
projCS.Direction(),
|
||||
projCS.XDirection());
|
||||
gp_Trsf fromR3;
|
||||
fromR3.SetTransformation(R3, proj3);
|
||||
BRepBuilderAPI_Transform xformer(fromR3);
|
||||
xformer.Perform(scaledSection, true);
|
||||
if (xformer.IsDone()) {
|
||||
sectionTopoDSFaces = TopoDS::Compound(xformer.Shape());
|
||||
} else {
|
||||
Base::Console().Message("DVS::sectionExec - face xform failed\n");
|
||||
m_sectionTopoDSFaces = alignSectionFaces(faceIntersections);
|
||||
if (debugSection()) {
|
||||
BRepTools::Write(m_sectionTopoDSFaces, "DVSTopoSectionFaces.brep"); //debug
|
||||
}
|
||||
m_tdSectionFaces = makeTDSectionFaces(m_sectionTopoDSFaces);
|
||||
|
||||
sectionTopoDSFaces = TopoDS::Compound(GeometryObject::invertGeometry(sectionTopoDSFaces)); //handle Qt -y
|
||||
|
||||
//turn section faces into TD geometry
|
||||
tdSectionFaces.clear();
|
||||
TopExp_Explorer sectionExpl(sectionTopoDSFaces, TopAbs_FACE);
|
||||
for (; sectionExpl.More(); sectionExpl.Next()) {
|
||||
const TopoDS_Face& face = TopoDS::Face(sectionExpl.Current());
|
||||
TechDraw::FacePtr sectionFace(std::make_shared<TechDraw::Face>());
|
||||
TopExp_Explorer expFace(face, TopAbs_WIRE);
|
||||
for ( ; expFace.More(); expFace.Next()) {
|
||||
TechDraw::Wire* w = new TechDraw::Wire();
|
||||
const TopoDS_Wire& wire = TopoDS::Wire(expFace.Current());
|
||||
TopExp_Explorer expWire(wire, TopAbs_EDGE);
|
||||
for ( ; expWire.More(); expWire.Next()) {
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(expWire.Current());
|
||||
TechDraw::BaseGeomPtr e = BaseGeom::baseFactory(edge);
|
||||
if (e) {
|
||||
w->geoms.push_back(e);
|
||||
}
|
||||
}
|
||||
sectionFace->wires.push_back(w);
|
||||
}
|
||||
tdSectionFaces.push_back(sectionFace);
|
||||
}
|
||||
|
||||
TechDraw::DrawViewPart* dvp = dynamic_cast<TechDraw::DrawViewPart*>(BaseView.getValue());
|
||||
if (dvp) {
|
||||
dvp->requestPaint(); //to refresh section line
|
||||
}
|
||||
requestPaint();
|
||||
requestPaint(); //this will be a duplicate paint if we are making a standalone ComplexSection
|
||||
}
|
||||
|
||||
//activities that depend on a valid section cut
|
||||
void DrawViewSection::postSectionCutTasks()
|
||||
{
|
||||
// Base::Console().Message("DVS::postSectionCutTasks()\n");
|
||||
std::vector<App::DocumentObject*> children = getInList();
|
||||
for (auto& c: children) {
|
||||
if (c->getTypeId().isDerivedFrom(DrawViewPart::getClassTypeId())) {
|
||||
@@ -529,16 +567,24 @@ gp_Pln DrawViewSection::getSectionPlane() const
|
||||
}
|
||||
|
||||
//! tries to find the intersection of the section plane with the shape giving a collection of planar faces
|
||||
//! the original algo finds the intersections first then transforms them to match the centered, rotated
|
||||
//! and scaled cut shape. Piecewise complex sections need to intersect the final cut shape (which in this
|
||||
//! case is a compound of individual cuts) with the "effective" (flattened) section plane.
|
||||
TopoDS_Compound DrawViewSection::findSectionPlaneIntersections(const TopoDS_Shape& shape)
|
||||
{
|
||||
// Base::Console().Message("DVS::findSectionPlaneIntersections() - %s\n", getNameInDocument());
|
||||
if(shape.IsNull()){
|
||||
// this shouldn't happen
|
||||
Base::Console().Warning("DrawViewSection::findSectionPlaneInter - %s - input shape is Null\n", getNameInDocument());
|
||||
// Base::Console().Warning("DrawViewSection::findSectionPlaneInter - %s - input shape is Null\n", getNameInDocument());
|
||||
return TopoDS_Compound();
|
||||
}
|
||||
|
||||
gp_Pln plnSection = getSectionPlane();
|
||||
if (debugSection()) {
|
||||
BRepBuilderAPI_MakeFace mkFace(plnSection, -m_shapeSize, m_shapeSize, -m_shapeSize, m_shapeSize);
|
||||
BRepTools::Write(mkFace.Face(), "DVSSectionPlane.brep"); //debug
|
||||
BRepTools::Write(shape, "DVSShapeToIntersect.brep)");
|
||||
}
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound result;
|
||||
builder.MakeCompound(result);
|
||||
@@ -558,6 +604,109 @@ TopoDS_Compound DrawViewSection::findSectionPlaneIntersections(const TopoDS_Shap
|
||||
return result;
|
||||
}
|
||||
|
||||
//move section faces to line up with cut shape
|
||||
TopoDS_Compound DrawViewSection::alignSectionFaces(TopoDS_Shape faceIntersections)
|
||||
{
|
||||
// Base::Console().Message("DVS::alignSectionFaces()\n");
|
||||
TopoDS_Compound sectionFaces;
|
||||
TopoDS_Shape centeredShape = TechDraw::moveShape(faceIntersections,
|
||||
getOriginalCentroid() * -1.0);
|
||||
|
||||
TopoDS_Shape scaledSection = TechDraw::scaleShape(centeredShape,
|
||||
getScale());
|
||||
if (!DrawUtil::fpCompare(Rotation.getValue(), 0.0)) {
|
||||
scaledSection = TechDraw::rotateShape(scaledSection,
|
||||
getSectionCS(),
|
||||
Rotation.getValue());
|
||||
}
|
||||
if (debugSection()) {
|
||||
BRepTools::Write(scaledSection, "DVSScaledFaces.brep"); //debug
|
||||
}
|
||||
|
||||
return mapToPage(scaledSection);
|
||||
}
|
||||
|
||||
TopoDS_Compound DrawViewSection::mapToPage(TopoDS_Shape& shapeToAlign)
|
||||
{
|
||||
// shapeToAlign is compound of TopoDS_Face intersections, but aligned to pln(origin, sectionNormal)
|
||||
// needs to be aligned to paper plane (origin, stdZ);
|
||||
//project the faces in the shapeToAlign, build new faces from the resulting wires and
|
||||
//combine everything into a compound of faces
|
||||
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound result;
|
||||
builder.MakeCompound(result);
|
||||
|
||||
TopExp_Explorer expFace(shapeToAlign, TopAbs_FACE);
|
||||
for (int iFace = 1; expFace.More(); expFace.Next(), iFace++) {
|
||||
const TopoDS_Face& face = TopoDS::Face(expFace.Current());
|
||||
std::vector<TopoDS_Wire> faceWires;
|
||||
TopExp_Explorer expWires(face, TopAbs_WIRE);
|
||||
for ( ; expWires.More(); expWires.Next()) {
|
||||
const TopoDS_Wire& wire = TopoDS::Wire(expWires.Current());
|
||||
TopoDS_Shape projectedShape = GeometryObject::projectSimpleShape(wire, getSectionCS());
|
||||
std::vector<TopoDS_Edge> wireEdges;
|
||||
//projectedShape is just a bunch of edges. we have to rebuild the wire.
|
||||
TopExp_Explorer expEdges(projectedShape, TopAbs_EDGE);
|
||||
for ( ; expEdges.More(); expEdges.Next()) {
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(expEdges.Current());
|
||||
wireEdges.push_back(edge);
|
||||
}
|
||||
TopoDS_Wire cleanWire = EdgeWalker::makeCleanWire(wireEdges, 2.0 * EWTOLERANCE);
|
||||
faceWires.push_back(cleanWire);
|
||||
}
|
||||
if (debugSection()) {
|
||||
std::stringstream ss;
|
||||
ss << "DVSFaceWires" << iFace << ".brep";
|
||||
BRepTools::Write(DrawUtil::vectorToCompound(faceWires), ss.str().c_str()); //debug
|
||||
}
|
||||
//first wire should be the outer boundary of the face
|
||||
BRepBuilderAPI_MakeFace mkFace(faceWires.front());
|
||||
int wireCount = faceWires.size();
|
||||
for (int iWire = 1; iWire < wireCount; iWire++) {
|
||||
//make holes in the face with the rest of the wires
|
||||
mkFace.Add(faceWires.at(iWire));
|
||||
}
|
||||
builder.Add(result, mkFace.Face());
|
||||
if (debugSection()) {
|
||||
std::stringstream ss;
|
||||
ss << "DVSFaceFromWires" << iFace << ".brep";
|
||||
BRepTools::Write(mkFace.Face(), ss.str().c_str()); //debug
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//turn OCC section faces into TD geometry
|
||||
std::vector<TechDraw::FacePtr> DrawViewSection::makeTDSectionFaces(TopoDS_Compound topoDSFaces)
|
||||
{
|
||||
// Base::Console().Message("DVS::makeTDSectionFaces()\n");
|
||||
std::vector<TechDraw::FacePtr> tdSectionFaces;
|
||||
TopExp_Explorer sectionExpl(topoDSFaces, TopAbs_FACE);
|
||||
for (; sectionExpl.More(); sectionExpl.Next()) {
|
||||
const TopoDS_Face& face = TopoDS::Face(sectionExpl.Current());
|
||||
TechDraw::FacePtr sectionFace(std::make_shared<TechDraw::Face>());
|
||||
TopExp_Explorer expFace(face, TopAbs_WIRE);
|
||||
for ( ; expFace.More(); expFace.Next()) {
|
||||
TechDraw::Wire* w = new TechDraw::Wire();
|
||||
const TopoDS_Wire& wire = TopoDS::Wire(expFace.Current());
|
||||
TopExp_Explorer expWire(wire, TopAbs_EDGE);
|
||||
for ( ; expWire.More(); expWire.Next()) {
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(expWire.Current());
|
||||
TechDraw::BaseGeomPtr e = BaseGeom::baseFactory(edge);
|
||||
if (e) {
|
||||
w->geoms.push_back(e);
|
||||
}
|
||||
}
|
||||
sectionFace->wires.push_back(w);
|
||||
}
|
||||
tdSectionFaces.push_back(sectionFace);
|
||||
}
|
||||
|
||||
return tdSectionFaces;
|
||||
}
|
||||
|
||||
//calculate the ends of the section line in BaseView's coords
|
||||
std::pair<Base::Vector3d, Base::Vector3d> DrawViewSection::sectionLineEnds()
|
||||
{
|
||||
@@ -662,8 +811,6 @@ void DrawViewSection::setCSFromBase(const std::string sectionName)
|
||||
gp_Ax2 DrawViewSection::getCSFromBase(const std::string sectionName) const
|
||||
{
|
||||
// Base::Console().Message("DVS::getCSFromBase(%s)\n", sectionName.c_str());
|
||||
Base::Vector3d sectionNormal;
|
||||
Base::Vector3d sectionXDir;
|
||||
Base::Vector3d origin(0.0, 0.0, 0.0);
|
||||
Base::Vector3d sectOrigin = SectionOrigin.getValue();
|
||||
|
||||
@@ -693,6 +840,12 @@ gp_Ax2 DrawViewSection::getCSFromBase(const std::string sectionName) const
|
||||
} else if (sectionName == "Right") {
|
||||
dvsDir = dvpRight.Reversed();
|
||||
dvsXDir = dvpDir;
|
||||
} else if (sectionName == "Aligned") {
|
||||
//if aligned, we don't get our direction from the base view
|
||||
Base::Vector3d sectionNormal = SectionNormal.getValue();
|
||||
dvsDir = gp_Dir(sectionNormal.x, sectionNormal.y, sectionNormal.z);
|
||||
Base::Vector3d sectionXDir = XDirection.getValue();
|
||||
dvsXDir = gp_Dir(sectionXDir.x, sectionXDir.y, sectionXDir.z);
|
||||
} else {
|
||||
Base::Console().Log("Error - DVS::getCSFromBase - bad sectionName: %s\n", sectionName.c_str());
|
||||
dvsDir = dvpRight;
|
||||
@@ -752,7 +905,7 @@ std::vector<LineSet> DrawViewSection::getDrawableLines(int i)
|
||||
TopoDS_Face DrawViewSection::getSectionTopoDSFace(int i)
|
||||
{
|
||||
TopoDS_Face result;
|
||||
TopExp_Explorer expl(sectionTopoDSFaces, TopAbs_FACE);
|
||||
TopExp_Explorer expl(m_sectionTopoDSFaces, TopAbs_FACE);
|
||||
int count = 1;
|
||||
for (; expl.More(); expl.Next(), count++) {
|
||||
if (count == i+1) {
|
||||
|
||||
@@ -94,26 +94,37 @@ public:
|
||||
short mustExecute() const override;
|
||||
|
||||
void sectionExec(TopoDS_Shape& s);
|
||||
void makeSectionCut(TopoDS_Shape &baseShape);
|
||||
virtual void makeSectionCut(TopoDS_Shape &baseShape);
|
||||
void postHlrTasks(void) override;
|
||||
virtual void postSectionCutTasks();
|
||||
void waitingForCut(bool s) { m_waitingForCut = s; }
|
||||
bool waitingForCut(void) const { return m_waitingForCut; }
|
||||
bool waitingForResult() const override;
|
||||
|
||||
std::vector<TechDraw::FacePtr> getTDFaceGeometry() {return tdSectionFaces;}
|
||||
|
||||
virtual TopoDS_Shape makeCuttingTool(double shapeSize);
|
||||
virtual TopoDS_Shape getShapeToCut();
|
||||
virtual bool isBaseValid() const;
|
||||
virtual TopoDS_Shape prepareShape(const TopoDS_Shape& rawShape,
|
||||
double shapeSize);
|
||||
virtual TopoDS_Shape getShapeToPrepare() const { return m_cutPieces; }
|
||||
//CS related methods
|
||||
void setCSFromBase(const std::string sectionName);
|
||||
gp_Ax2 getCSFromBase(const std::string sectionName) const;
|
||||
|
||||
virtual gp_Ax2 getCSFromBase(const std::string sectionName) const;
|
||||
gp_Ax2 getSectionCS() const;
|
||||
Base::Vector3d getXDirection() const override; //don't use XDirection.getValue()
|
||||
|
||||
TechDraw::DrawViewPart* getBaseDVP() const;
|
||||
TechDraw::DrawProjGroupItem* getBaseDPGI() const;
|
||||
|
||||
TopoDS_Compound getSectionTFaces() { return sectionTopoDSFaces;}
|
||||
//section face related methods
|
||||
TopoDS_Compound getSectionTFaces() { return m_sectionTopoDSFaces;}
|
||||
std::vector<TechDraw::FacePtr> getTDFaceGeometry() {return m_tdSectionFaces;}
|
||||
TopoDS_Face getSectionTopoDSFace(int i);
|
||||
virtual TopoDS_Compound alignSectionFaces(TopoDS_Shape faceIntersections);
|
||||
TopoDS_Compound mapToPage(TopoDS_Shape& shapeToAlign);
|
||||
virtual std::vector<TechDraw::FacePtr> makeTDSectionFaces(TopoDS_Compound topoDSFaces);
|
||||
virtual TopoDS_Shape getShapeToIntersect() { return m_cutPieces; }
|
||||
|
||||
void makeLineSets(void) ;
|
||||
std::vector<LineSet> getDrawableLines(int i = 0);
|
||||
std::vector<PATLineSpec> getDecodedSpecsFromFile(std::string fileSpec, std::string myPattern);
|
||||
@@ -123,7 +134,7 @@ public:
|
||||
static const char* SectionDirEnums[];
|
||||
static const char* CutSurfaceEnums[];
|
||||
|
||||
std::pair<Base::Vector3d, Base::Vector3d> sectionLineEnds();
|
||||
virtual std::pair<Base::Vector3d, Base::Vector3d> sectionLineEnds();
|
||||
|
||||
bool showSectionEdges(void);
|
||||
|
||||
@@ -131,13 +142,13 @@ public Q_SLOTS:
|
||||
void onSectionCutFinished(void);
|
||||
|
||||
protected:
|
||||
TopoDS_Compound sectionTopoDSFaces; //needed for hatching
|
||||
TopoDS_Compound m_sectionTopoDSFaces; //needed for hatching
|
||||
std::vector<LineSet> m_lineSets;
|
||||
std::vector<TechDraw::FacePtr> tdSectionFaces;
|
||||
std::vector<TechDraw::FacePtr> m_tdSectionFaces;
|
||||
|
||||
|
||||
gp_Pln getSectionPlane() const;
|
||||
TopoDS_Compound findSectionPlaneIntersections(const TopoDS_Shape& shape);
|
||||
virtual gp_Pln getSectionPlane() const;
|
||||
virtual TopoDS_Compound findSectionPlaneIntersections(const TopoDS_Shape& shape);
|
||||
void getParameters();
|
||||
bool debugSection() const;
|
||||
int prefCutSurface() const;
|
||||
@@ -151,15 +162,16 @@ protected:
|
||||
void replaceSvgIncluded(std::string newSvgFile);
|
||||
void replacePatIncluded(std::string newPatFile);
|
||||
|
||||
TopoDS_Shape m_rawShape;
|
||||
gp_Ax2 m_viewAxis;
|
||||
TopoDS_Shape m_scaledShape;
|
||||
TopoDS_Shape m_cutPieces; //the shape after cutting, but before centering & scaling
|
||||
gp_Ax2 m_projectionCS;
|
||||
TopoDS_Shape m_preparedShape; //the shape after cutting, centering, scaling etc
|
||||
|
||||
QMetaObject::Connection connectCutWatcher;
|
||||
QFutureWatcher<void> m_cutWatcher;
|
||||
QFuture<void> m_cutFuture;
|
||||
bool m_waitingForCut;
|
||||
|
||||
TopoDS_Shape m_cuttingTool;
|
||||
double m_shapeSize;
|
||||
};
|
||||
|
||||
using DrawViewSectionPython = App::FeaturePythonT<DrawViewSection>;
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <iomanip>
|
||||
# include <sstream>
|
||||
# include <boost/regex.hpp>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <boost/regex.hpp>
|
||||
#endif
|
||||
|
||||
#include <App/Property.h>
|
||||
@@ -34,10 +34,10 @@
|
||||
#include <Mod/Spreadsheet/App/Cell.h>
|
||||
#include <Mod/Spreadsheet/App/Sheet.h>
|
||||
|
||||
#include "DrawViewSpreadsheet.h"
|
||||
#include "DrawUtil.h"
|
||||
#include "Preferences.h"
|
||||
|
||||
#include "DrawViewSpreadsheet.h"
|
||||
|
||||
using namespace TechDraw;
|
||||
|
||||
|
||||
@@ -1246,8 +1246,8 @@ bool BSpline::isLine()
|
||||
return false;
|
||||
}
|
||||
|
||||
Base::Vector3d vs = DrawUtil::gpPnt2V3(s);
|
||||
Base::Vector3d ve = DrawUtil::gpPnt2V3(e);
|
||||
Base::Vector3d vs = DrawUtil::toVector3d(s);
|
||||
Base::Vector3d ve = DrawUtil::toVector3d(e);
|
||||
double endLength = (vs - ve).Length();
|
||||
int low = 0;
|
||||
int high = spline->NbPoles() - 1;
|
||||
@@ -1256,9 +1256,9 @@ bool BSpline::isLine()
|
||||
double lenTotal = 0.0;
|
||||
for (int i = 0; i < high; i++) {
|
||||
gp_Pnt p1 = poles(i);
|
||||
Base::Vector3d v1 = DrawUtil::gpPnt2V3(p1);
|
||||
Base::Vector3d v1 = DrawUtil::toVector3d(p1);
|
||||
gp_Pnt p2 = poles(i+1);
|
||||
Base::Vector3d v2 = DrawUtil::gpPnt2V3(p2);
|
||||
Base::Vector3d v2 = DrawUtil::toVector3d(p2);
|
||||
lenTotal += (v2-v1).Length();
|
||||
}
|
||||
|
||||
@@ -1415,7 +1415,7 @@ TopoDS_Edge BSpline::asCircle(bool& arc)
|
||||
gp_Circ circle1 = gce_circ1.Value();
|
||||
double radius1 = circle1.Radius();
|
||||
gp_Pnt center1 = circle1.Location();
|
||||
Base::Vector3d vc1 = DrawUtil::gpPnt2V3(center1);
|
||||
Base::Vector3d vc1 = DrawUtil::toVector3d(center1);
|
||||
|
||||
gce_MakeCirc gce_circ2 = gce_MakeCirc(pcm, pc2, e);
|
||||
if (gce_circ2.Status() != gce_Done) {
|
||||
@@ -1424,7 +1424,7 @@ TopoDS_Edge BSpline::asCircle(bool& arc)
|
||||
gp_Circ circle2 = gce_circ2.Value();
|
||||
double radius2 = circle2.Radius();
|
||||
gp_Pnt center2 = circle2.Location();
|
||||
Base::Vector3d vc2 = DrawUtil::gpPnt2V3(center2);
|
||||
Base::Vector3d vc2 = DrawUtil::toVector3d(center2);
|
||||
|
||||
// compare radii & centers
|
||||
double allowError = 0.001; //mm^-3 good enough for printing
|
||||
|
||||
@@ -24,13 +24,20 @@
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRepAlgo_NormalProjection.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
#include <BRepBuilderAPI_Copy.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
#include <BRepBuilderAPI_Transform.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRepLib.hxx>
|
||||
#include <BRepLib.hxx>
|
||||
#include <BRepLProp_CLProps.hxx>
|
||||
#include <BRepLProp_CurveTool.hxx>
|
||||
#include <BRepMesh_IncrementalMesh.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <gp_Ax1.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
@@ -39,17 +46,17 @@
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <HLRBRep.hxx>
|
||||
#include <HLRAlgo_Projector.hxx>
|
||||
#include <HLRBRep_Algo.hxx>
|
||||
#include <HLRBRep_HLRToShape.hxx>
|
||||
#include <HLRBRep.hxx>
|
||||
#include <HLRBRep_PolyAlgo.hxx>
|
||||
#include <HLRAlgo_Projector.hxx>
|
||||
#include <HLRBRep_PolyHLRToShape.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#endif // #ifndef _PreComp_
|
||||
@@ -70,6 +77,8 @@
|
||||
using namespace TechDraw;
|
||||
using namespace std;
|
||||
|
||||
using DU = DrawUtil;
|
||||
|
||||
struct EdgePoints {
|
||||
gp_Pnt v1, v2;
|
||||
TopoDS_Edge edge;
|
||||
@@ -180,6 +189,7 @@ void GeometryObject::projectShape(const TopoDS_Shape& inShape,
|
||||
visHard = hlrToShape.VCompound();
|
||||
BRepLib::BuildCurves3d(visHard);
|
||||
visHard = invertGeometry(visHard);
|
||||
BRepTools::Write(visHard, "GOvisHard.brep"); //debug
|
||||
}
|
||||
|
||||
if (!hlrToShape.Rg1LineVCompound().IsNull()) {
|
||||
@@ -417,6 +427,46 @@ void GeometryObject::projectShapeWithPolygonAlgo(const TopoDS_Shape& input,
|
||||
makeTDGeometry();
|
||||
}
|
||||
|
||||
//project the edges in shape onto XY.mirrored plane of CS. mimics the projection
|
||||
//of the main hlr routine. Only the visible hard edges are returned, so this method
|
||||
//is only suitable for simple shapes that have no hidden edges, like faces or wires.
|
||||
//TODO: allow use of perspective projector
|
||||
TopoDS_Shape GeometryObject::projectSimpleShape(const TopoDS_Shape &shape,
|
||||
const gp_Ax2 &CS)
|
||||
{
|
||||
// Base::Console().Message("GO::()\n");
|
||||
if(shape.IsNull()) {
|
||||
throw Base::ValueError("GO::projectSimpleShape - input shape is NULL");
|
||||
}
|
||||
|
||||
HLRBRep_Algo *brep_hlr = new HLRBRep_Algo();
|
||||
brep_hlr->Add(shape);
|
||||
HLRAlgo_Projector projector( CS );
|
||||
brep_hlr->Projector(projector);
|
||||
brep_hlr->Update();
|
||||
brep_hlr->Hide();
|
||||
|
||||
HLRBRep_HLRToShape hlrToShape(brep_hlr);
|
||||
TopoDS_Shape hardEdges = hlrToShape.VCompound();
|
||||
BRepLib::BuildCurves3d(hardEdges);
|
||||
hardEdges = invertGeometry(hardEdges);
|
||||
|
||||
return hardEdges;
|
||||
}
|
||||
|
||||
//project the edges of a shape onto the XY plane of projCS. This does not give
|
||||
//the same result as the hlr projections
|
||||
TopoDS_Shape GeometryObject::simpleProjection(const TopoDS_Shape& shape,
|
||||
const gp_Ax2& projCS)
|
||||
{
|
||||
gp_Pln plane(projCS);
|
||||
TopoDS_Face paper = BRepBuilderAPI_MakeFace(plane);
|
||||
BRepAlgo_NormalProjection projector(paper);
|
||||
projector.Add(shape);
|
||||
projector.Build();
|
||||
return projector.Projection();
|
||||
}
|
||||
|
||||
TopoDS_Shape GeometryObject::projectFace(const TopoDS_Shape &face,
|
||||
const gp_Ax2 &CS)
|
||||
{
|
||||
@@ -510,11 +560,11 @@ void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass ca
|
||||
Base::Console().Log("GO::addGeomFromCompound - edge: %d is NULL\n", i);
|
||||
continue;
|
||||
}
|
||||
if (DrawUtil::isZeroEdge(edge)) {
|
||||
if (DU::isZeroEdge(edge)) {
|
||||
Base::Console().Log("GO::addGeomFromCompound - edge: %d is zeroEdge\n", i);
|
||||
continue;
|
||||
}
|
||||
if (DrawUtil::isCrazy(edge)) {
|
||||
if (DU::isCrazy(edge)) {
|
||||
Base::Console().Log("GO::addGeomFromCompound - edge: %d is crazy\n", i);
|
||||
continue;
|
||||
}
|
||||
@@ -860,7 +910,7 @@ gp_Ax2 TechDraw::getViewAxis(const Base::Vector3d origin,
|
||||
Base::Vector3d stdZ(0.0, 0.0, 1.0);
|
||||
Base::Vector3d stdOrg(0.0, 0.0, 0.0);
|
||||
Base::Vector3d cross = direction;
|
||||
if (TechDraw::DrawUtil::checkParallel(direction, stdZ)) {
|
||||
if (DU::checkParallel(direction, stdZ)) {
|
||||
cross = Base::Vector3d(1.0, 0.0, 0.0);
|
||||
} else {
|
||||
cross.Normalize();
|
||||
@@ -913,7 +963,7 @@ gp_Ax2 TechDraw::legacyViewAxis1(const Base::Vector3d origin,
|
||||
}
|
||||
Base::Vector3d cross = flipDirection;
|
||||
// //special case
|
||||
if (TechDraw::DrawUtil::checkParallel(flipDirection, stdZ)) {
|
||||
if (DU::checkParallel(flipDirection, stdZ)) {
|
||||
cross = Base::Vector3d(1.0, 0.0, 0.0);
|
||||
} else {
|
||||
cross.Normalize();
|
||||
@@ -940,6 +990,23 @@ gp_Ax2 TechDraw::legacyViewAxis1(const Base::Vector3d origin,
|
||||
return viewAxis;
|
||||
}
|
||||
|
||||
//! Returns the centroid of shape based on R3
|
||||
gp_Pnt TechDraw::findCentroid(const TopoDS_Shape& shape)
|
||||
{
|
||||
Bnd_Box tBounds;
|
||||
tBounds.SetGap(0.0);
|
||||
BRepBndLib::AddOptimal(shape, tBounds, true, false);
|
||||
|
||||
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;
|
||||
|
||||
return gp_Pnt(x, y, z);
|
||||
}
|
||||
|
||||
//! Returns the centroid of shape, as viewed according to direction
|
||||
gp_Pnt TechDraw::findCentroid(const TopoDS_Shape &shape,
|
||||
const Base::Vector3d &direction)
|
||||
@@ -955,8 +1022,6 @@ gp_Pnt TechDraw::findCentroid(const TopoDS_Shape &shape,
|
||||
const gp_Ax2 &viewAxis)
|
||||
{
|
||||
// Base::Console().Message("GO::findCentroid() - 2\n");
|
||||
// Base::Vector3d origin(0.0, 0.0, 0.0);
|
||||
// gp_Ax2 viewAxis = getViewAxis(origin, direction);
|
||||
|
||||
gp_Trsf tempTransform;
|
||||
tempTransform.SetTransformation(viewAxis);
|
||||
@@ -1020,7 +1085,7 @@ TopoDS_Shape TechDraw::mirrorShape(const TopoDS_Shape &input,
|
||||
// mirror about the Y axis
|
||||
gp_Trsf tempTransform;
|
||||
//BRepBuilderAPI_Transform will loop forever if asked to use 0.0 as scale
|
||||
if (!(scale > 0.0)) {
|
||||
if (scale <= 0.0) {
|
||||
tempTransform.SetScale(inputCenter, 1.0);
|
||||
} else {
|
||||
tempTransform.SetScale(inputCenter, scale);
|
||||
@@ -1042,8 +1107,8 @@ TopoDS_Shape TechDraw::mirrorShape(const TopoDS_Shape &input,
|
||||
|
||||
//!rotates a shape about a viewAxis
|
||||
TopoDS_Shape TechDraw::rotateShape(const TopoDS_Shape &input,
|
||||
gp_Ax2& viewAxis,
|
||||
double rotAngle)
|
||||
const gp_Ax2 &viewAxis,
|
||||
double rotAngle)
|
||||
{
|
||||
TopoDS_Shape transShape;
|
||||
if (input.IsNull()) {
|
||||
@@ -1103,3 +1168,62 @@ TopoDS_Shape TechDraw::moveShape(const TopoDS_Shape &input,
|
||||
}
|
||||
return transShape;
|
||||
}
|
||||
|
||||
|
||||
//!moves a shape with restricts on directions
|
||||
TopoDS_Shape TechDraw::moveShapeRestricted(const TopoDS_Shape &input,
|
||||
const Base::Vector3d& motion,
|
||||
bool allowX,
|
||||
bool allowY,
|
||||
bool allowZ)
|
||||
{
|
||||
gp_Vec gMotion(allowX ? motion.x : 0.0,
|
||||
allowY ? motion.y : 0.0,
|
||||
allowZ ? motion.z : 0.0);
|
||||
TopoDS_Shape transShape;
|
||||
try {
|
||||
gp_Trsf xlate;
|
||||
xlate.SetTranslation(gMotion);
|
||||
|
||||
BRepBuilderAPI_Transform mkTrf(input, xlate);
|
||||
transShape = mkTrf.Shape();
|
||||
}
|
||||
catch (...) {
|
||||
Base::Console().Log("GeometryObject::moveShapeRestricted - move failed.\n");
|
||||
return transShape;
|
||||
}
|
||||
return transShape;
|
||||
}
|
||||
|
||||
//!moves a shape with restricts on directions
|
||||
TopoDS_Shape TechDraw::moveShapeRestricted(const TopoDS_Shape &input,
|
||||
const Base::Vector3d& motion,
|
||||
const Base::Vector3d& mask)
|
||||
{
|
||||
gp_Vec gMotion(mask.x ? motion.x : 0.0,
|
||||
mask.y ? motion.y : 0.0,
|
||||
mask.z ? motion.z : 0.0);
|
||||
|
||||
TopoDS_Shape transShape;
|
||||
try {
|
||||
gp_Trsf xlate;
|
||||
xlate.SetTranslation(gMotion);
|
||||
|
||||
BRepBuilderAPI_Transform mkTrf(input, xlate);
|
||||
transShape = mkTrf.Shape();
|
||||
}
|
||||
catch (...) {
|
||||
Base::Console().Log("GeometryObject::moveShapeRestricted - move failed.\n");
|
||||
return transShape;
|
||||
}
|
||||
return transShape;
|
||||
}
|
||||
|
||||
TopoDS_Shape TechDraw::moveShapeRestricted(const TopoDS_Shape &input,
|
||||
const gp_Vec& motion,
|
||||
const gp_Vec& mask)
|
||||
{
|
||||
return moveShapeRestricted(input,
|
||||
DU::toVector3d(motion),
|
||||
DU::toVector3d(mask));
|
||||
}
|
||||
|
||||
@@ -67,13 +67,24 @@ TopoDS_Shape TechDrawExport mirrorShape(const TopoDS_Shape &input,
|
||||
TopoDS_Shape TechDrawExport scaleShape(const TopoDS_Shape &input,
|
||||
double scale);
|
||||
TopoDS_Shape TechDrawExport rotateShape(const TopoDS_Shape &input,
|
||||
gp_Ax2& viewAxis,
|
||||
double rotAngle);
|
||||
const gp_Ax2& viewAxis,
|
||||
double rotAngle);
|
||||
TopoDS_Shape TechDrawExport moveShape(const TopoDS_Shape &input,
|
||||
const Base::Vector3d& motion);
|
||||
|
||||
TopoDS_Shape TechDrawExport moveShapeRestricted(const TopoDS_Shape &input,
|
||||
const Base::Vector3d& motion,
|
||||
bool allowX = true,
|
||||
bool allowY = true,
|
||||
bool allowZ = true);
|
||||
TopoDS_Shape TechDrawExport moveShapeRestricted(const TopoDS_Shape &input,
|
||||
const Base::Vector3d& motion,
|
||||
const Base::Vector3d& mask);
|
||||
TopoDS_Shape TechDrawExport moveShapeRestricted(const TopoDS_Shape &input,
|
||||
const gp_Vec& motion,
|
||||
const gp_Vec& mask);
|
||||
|
||||
//! Returns the centroid of shape, as viewed according to direction
|
||||
gp_Pnt TechDrawExport findCentroid(const TopoDS_Shape& shape);
|
||||
gp_Pnt TechDrawExport findCentroid(const TopoDS_Shape &shape,
|
||||
const Base::Vector3d &direction);
|
||||
gp_Pnt TechDrawExport findCentroid(const TopoDS_Shape &shape,
|
||||
@@ -118,9 +129,12 @@ public:
|
||||
const gp_Ax2 &viewAxis);
|
||||
void projectShapeWithPolygonAlgo(const TopoDS_Shape &input,
|
||||
const gp_Ax2 &viewAxis);
|
||||
TopoDS_Shape projectFace(const TopoDS_Shape &face,
|
||||
const gp_Ax2 &CS);
|
||||
|
||||
static TopoDS_Shape projectSimpleShape(const TopoDS_Shape &shape,
|
||||
const gp_Ax2 &CS);
|
||||
static TopoDS_Shape simpleProjection(const TopoDS_Shape& shape,
|
||||
const gp_Ax2& projCS);
|
||||
static TopoDS_Shape projectFace(const TopoDS_Shape &face,
|
||||
const gp_Ax2 &CS);
|
||||
void makeTDGeometry();
|
||||
void extractGeometry(edgeClass category, bool visible);
|
||||
void addFaceGeom(FacePtr f);
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <chrono>
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
@@ -132,7 +132,28 @@ double Preferences::vertexScale()
|
||||
return result;
|
||||
}
|
||||
|
||||
int Preferences::scaleType()
|
||||
{
|
||||
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
|
||||
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/General");
|
||||
int result = hGrp->GetInt("DefaultScaleType", 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
double Preferences::scale()
|
||||
{
|
||||
int prefScaleType = scaleType();
|
||||
if (prefScaleType == 0) { //page scale
|
||||
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
|
||||
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/General");
|
||||
return hGrp->GetFloat("DefaultPageScale", 1.0);
|
||||
} else if (prefScaleType == 1) { //custom scale
|
||||
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
|
||||
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/General");
|
||||
return hGrp->GetFloat("DefaultViewScale", 1.0);
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
//lightgray #D3D3D3
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ static App::Color selectColor();
|
||||
static App::Color preselectColor();
|
||||
static App::Color vertexColor();
|
||||
static double vertexScale();
|
||||
|
||||
static int scaleType();
|
||||
static double scale();
|
||||
static bool useGlobalDecimals();
|
||||
static bool keepPagesUpToDate();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user