aports/testing/freecad/opencascade76.patch

3697 lines
150 KiB
Diff

Patches FreeCAD to work with OpenCascade v7.6.0 using upstream commits
that resolve the issue. This patch can be removed once FreeCAD v0.20.0
is released as it will be compatible with OpenCascade v7.6.0
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/6f3b00d67ec0bd0072b7b493e2a38d2a2e3af27d.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/77b198048a63f1e9ca15eef64c8042d599a14cf3.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/9b4db7e06472bf5550d0b7627b28b425bfcc8470.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/74639da997d5f2e53f001d9f256be86ceee901f5.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/c9d17ebde2400f83d1e1e799bdb0a7f85a0da96d.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/442c8d52a1989da8f17d60fafea5b81d79cbf0ab.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/8e6dab209ee59be61d83a0ff249283a8809fa917.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/0f3b5d275070477b7cd2bbfa2dc930135448fb0c.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/08d46b5f882420c8d4066427fcc8dab5b1882097.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/51e4366085e59a9b511f7160d66493e9b3dfc7d8.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/c2c5ae1bf0c571270ecacf257a51e9b064fc609a.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/302568d177ddde171c28eaca89e8b4a49466974f.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/66d3dd897f63c2e4f8ffd6eced730c6a3372ad51.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/03be15cc6b460ab62548142287eb9f677f463a44.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/f628050732cc5d1d49fc18282ed508ca3061bb10.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/16ff933b09176d83fb0785e74f36038311f0eaeb.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/03da9d3501c6b596ad1828b99cb8d923cea56485.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/fecf9c2e8492ddab0858b4af23b56da36bff6f6a.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/8453d415150f289d36dfe4cbe6b91dfc512e82fe.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/3131b97aa88736ac628428a8ceb025d9b7a8a965.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/5b4c246944c72459016efff6ae903ac66c090991.patch
Patch-Source:https://github.com/FreeCAD/FreeCAD/commit/f55c46cc86344a6d7389156c015194f7d0fd2b63.patch
From 6f3b00d67ec0bd0072b7b493e2a38d2a2e3af27d Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Mon, 11 Oct 2021 00:30:22 +0200
Subject: [PATCH] SMESH: port to OCCT 7.6
---
.../src/NETGENPlugin/NETGENPlugin_Mesher.cpp | 7 +++++++
.../salomesmesh/src/SMESH/SMESH_MeshAlgos.cpp | 7 +++++--
.../src/StdMeshers/StdMeshers_Adaptive1D.cpp | 14 ++++++++++++++
.../src/StdMeshers/StdMeshers_Quadrangle_2D.cpp | 2 +-
.../src/StdMeshers/StdMeshers_ViscousLayers.cpp | 8 ++++++++
5 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/src/3rdParty/salomesmesh/src/NETGENPlugin/NETGENPlugin_Mesher.cpp b/src/3rdParty/salomesmesh/src/NETGENPlugin/NETGENPlugin_Mesher.cpp
index cd6f0b2b075..ea83984b976 100644
--- a/src/3rdParty/salomesmesh/src/NETGENPlugin/NETGENPlugin_Mesher.cpp
+++ b/src/3rdParty/salomesmesh/src/NETGENPlugin/NETGENPlugin_Mesher.cpp
@@ -56,6 +56,7 @@
#include <NCollection_Map.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_ProgramError.hxx>
+#include <Standard_Version.hxx>
#include <TColStd_MapOfInteger.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
@@ -700,7 +701,13 @@ double NETGENPlugin_Mesher::GetDefaultMinSize(const TopoDS_Shape& geom,
BRep_Tool::Triangulation ( TopoDS::Face( fExp.Current() ), loc);
if ( triangulation.IsNull() ) continue;
const double fTol = BRep_Tool::Tolerance( TopoDS::Face( fExp.Current() ));
+#if OCC_VERSION_HEX < 0x070600
const TColgp_Array1OfPnt& points = triangulation->Nodes();
+#else
+ auto points = [&triangulation](Standard_Integer index) {
+ return triangulation->Node(index);
+ };
+#endif
const Poly_Array1OfTriangle& trias = triangulation->Triangles();
for ( int iT = trias.Lower(); iT <= trias.Upper(); ++iT )
{
diff --git a/src/3rdParty/salomesmesh/src/SMESH/SMESH_MeshAlgos.cpp b/src/3rdParty/salomesmesh/src/SMESH/SMESH_MeshAlgos.cpp
index 5a07308310e..fbb1b250087 100644
--- a/src/3rdParty/salomesmesh/src/SMESH/SMESH_MeshAlgos.cpp
+++ b/src/3rdParty/salomesmesh/src/SMESH/SMESH_MeshAlgos.cpp
@@ -38,10 +38,13 @@
#include <GC_MakeSegment.hxx>
#include <GeomAPI_ExtremaCurveCurve.hxx>
#include <Geom_Line.hxx>
-#include <IntAna_IntConicQuad.hxx>
-#include <IntAna_Quadric.hxx>
+#include <gp_Cone.hxx>
+#include <gp_Cylinder.hxx>
#include <gp_Lin.hxx>
#include <gp_Pln.hxx>
+#include <gp_Sphere.hxx>
+#include <IntAna_IntConicQuad.hxx>
+#include <IntAna_Quadric.hxx>
#include <limits>
#include <numeric>
diff --git a/src/3rdParty/salomesmesh/src/StdMeshers/StdMeshers_Adaptive1D.cpp b/src/3rdParty/salomesmesh/src/StdMeshers/StdMeshers_Adaptive1D.cpp
index 88970f36b55..7c51601c7bb 100644
--- a/src/3rdParty/salomesmesh/src/StdMeshers/StdMeshers_Adaptive1D.cpp
+++ b/src/3rdParty/salomesmesh/src/StdMeshers/StdMeshers_Adaptive1D.cpp
@@ -46,6 +46,7 @@
#include <Poly_Array1OfTriangle.hxx>
#include <Poly_PolygonOnTriangulation.hxx>
#include <Poly_Triangulation.hxx>
+#include <Standard_Version.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
@@ -318,13 +319,26 @@ namespace // internal utils
{
myFaceTol = SMESH_MesherHelper::MaxTolerance( face );
myTree = triaTree;
+#if OCC_VERSION_HEX < 0x070600
myNodes = & tr->Nodes();
+#else
+ TColgp_Array1OfPnt* trNodes = new TColgp_Array1OfPnt( 1, tr->NbNodes() );
+ for (Standard_Integer i = myNodes->Lower(); i <= myNodes->Upper(); i++)
+ {
+ trNodes->SetValue(i, tr->Node(i));
+ }
+ myNodes = trNodes;
+ myOwnNodes = true;
+#endif
myPolyTrias = & tr->Triangles();
myTriasDeflection = tr->Deflection();
if ( !loc.IsIdentity() ) // transform nodes if necessary
{
TColgp_Array1OfPnt* trsfNodes = new TColgp_Array1OfPnt( myNodes->Lower(), myNodes->Upper() );
trsfNodes->Assign( *myNodes );
+#if OCC_VERSION_HEX >= 0x070600
+ delete myNodes; // it's already a copy
+#endif
myNodes = trsfNodes;
myOwnNodes = true;
const gp_Trsf& trsf = loc;
diff --git a/src/3rdParty/salomesmesh/src/StdMeshers/StdMeshers_Quadrangle_2D.cpp b/src/3rdParty/salomesmesh/src/StdMeshers/StdMeshers_Quadrangle_2D.cpp
index f7ac411d9a5..5d5c15c3661 100644
--- a/src/3rdParty/salomesmesh/src/StdMeshers/StdMeshers_Quadrangle_2D.cpp
+++ b/src/3rdParty/salomesmesh/src/StdMeshers/StdMeshers_Quadrangle_2D.cpp
@@ -50,7 +50,7 @@
#include <Geom_Surface.hxx>
#include <NCollection_DefineArray2.hxx>
#include <Precision.hxx>
-#include <Quantity_Parameter.hxx>
+#include <Standard_Real.hxx>
#include <TColStd_SequenceOfInteger.hxx>
#include <TColStd_SequenceOfReal.hxx>
#include <TColgp_SequenceOfXY.hxx>
diff --git a/src/3rdParty/salomesmesh/src/StdMeshers/StdMeshers_ViscousLayers.cpp b/src/3rdParty/salomesmesh/src/StdMeshers/StdMeshers_ViscousLayers.cpp
index 8ee0e268325..e9f46183059 100644
--- a/src/3rdParty/salomesmesh/src/StdMeshers/StdMeshers_ViscousLayers.cpp
+++ b/src/3rdParty/salomesmesh/src/StdMeshers/StdMeshers_ViscousLayers.cpp
@@ -44,7 +44,10 @@
#include "SMESH_subMeshEventListener.hxx"
#include "StdMeshers_FaceSide.hxx"
+#include <Standard_Version.hxx>
+#if OCC_VERSION_HEX < 0x070600
#include <Adaptor3d_HSurface.hxx>
+#endif
#include <BRepAdaptor_Curve2d.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepLProp_SLProps.hxx>
@@ -1340,8 +1343,13 @@ namespace VISCOUS_3D
//case GeomAbs_SurfaceOfExtrusion:
case GeomAbs_OffsetSurface:
{
+#if OCC_VERSION_HEX < 0x070600
Handle(Adaptor3d_HSurface) base = surface.BasisSurface();
return getRovolutionAxis( base->Surface(), axis );
+#else
+ Handle(Adaptor3d_Surface) base = surface.BasisSurface();
+ return getRovolutionAxis( *base, axis );
+#endif
}
default: return false;
}
From 77b198048a63f1e9ca15eef64c8042d599a14cf3 Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Thu, 7 Oct 2021 11:10:12 +0200
Subject: [PATCH] SMESH: [skip ci] do not undefine the guard of a header file
---
src/3rdParty/salomesmesh/src/SMESH/SMESH_Mesh.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/3rdParty/salomesmesh/src/SMESH/SMESH_Mesh.cpp b/src/3rdParty/salomesmesh/src/SMESH/SMESH_Mesh.cpp
index 24dc2d00a67..8e78712f4a4 100644
--- a/src/3rdParty/salomesmesh/src/SMESH/SMESH_Mesh.cpp
+++ b/src/3rdParty/salomesmesh/src/SMESH/SMESH_Mesh.cpp
@@ -64,7 +64,7 @@
#include <GEOMUtils.hxx>
-#undef _Precision_HeaderFile
+//#undef _Precision_HeaderFile
#include <BRepBndLib.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <Bnd_Box.hxx>
From 9b4db7e06472bf5550d0b7627b28b425bfcc8470 Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Fri, 8 Oct 2021 15:32:41 +0200
Subject: [PATCH] Part: in Part.getFacets() use functions of Tools class
---
src/Mod/Part/App/AppPartPy.cpp | 34 +++++++++++++---------------------
1 file changed, 13 insertions(+), 21 deletions(-)
diff --git a/src/Mod/Part/App/AppPartPy.cpp b/src/Mod/Part/App/AppPartPy.cpp
index 08e3e9fd470..f16ae7e221a 100644
--- a/src/Mod/Part/App/AppPartPy.cpp
+++ b/src/Mod/Part/App/AppPartPy.cpp
@@ -134,6 +134,7 @@
#include "PartFeature.h"
#include "PartPyCXX.h"
#include "modelRefine.h"
+#include "Tools.h"
#ifdef FCUseFreeType
# include "FT2FC.h"
@@ -804,33 +805,24 @@ class Module : public Py::ExtensionModule<Module>
auto theShape = static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->getShape();
for (TopExp_Explorer ex(theShape, TopAbs_FACE); ex.More(); ex.Next()) {
TopoDS_Face currentFace = TopoDS::Face(ex.Current());
- TopLoc_Location loc;
- Handle(Poly_Triangulation) facets = BRep_Tool::Triangulation(currentFace, loc);
- const TopAbs_Orientation anOrientation = currentFace.Orientation();
- bool flip = (anOrientation == TopAbs_REVERSED);
- if (!facets.IsNull()) {
- const TColgp_Array1OfPnt& nodes = facets->Nodes();
- const Poly_Array1OfTriangle& triangles = facets->Triangles();
- for (int i = 1; i <= triangles.Length(); i++) {
+
+ std::vector<gp_Pnt> points;
+ std::vector<Poly_Triangle> facets;
+ if (Tools::getTriangulation(currentFace, points, facets)) {
+ for (const auto& it : facets) {
Standard_Integer n1,n2,n3;
- triangles(i).Get(n1, n2, n3);
- gp_Pnt p1 = nodes(n1);
- gp_Pnt p2 = nodes(n2);
- gp_Pnt p3 = nodes(n3);
- p1.Transform(loc.Transformation());
- p2.Transform(loc.Transformation());
- p3.Transform(loc.Transformation());
+ it.Get(n1, n2, n3);
+
+ gp_Pnt p1 = points[n1];
+ gp_Pnt p2 = points[n2];
+ gp_Pnt p3 = points[n3];
+
// TODO: verify if tolerance should be hard coded
if (!p1.IsEqual(p2, 0.01) && !p2.IsEqual(p3, 0.01) && !p3.IsEqual(p1, 0.01)) {
PyObject *t1 = PyTuple_Pack(3, PyFloat_FromDouble(p1.X()), PyFloat_FromDouble(p1.Y()), PyFloat_FromDouble(p1.Z()));
PyObject *t2 = PyTuple_Pack(3, PyFloat_FromDouble(p2.X()), PyFloat_FromDouble(p2.Y()), PyFloat_FromDouble(p2.Z()));
PyObject *t3 = PyTuple_Pack(3, PyFloat_FromDouble(p3.X()), PyFloat_FromDouble(p3.Y()), PyFloat_FromDouble(p3.Z()));
- if (flip) {
- list.append(Py::asObject(PyTuple_Pack(3, t2, t1, t3)));
- }
- else {
- list.append(Py::asObject(PyTuple_Pack(3, t1, t2, t3)));
- }
+ list.append(Py::asObject(PyTuple_Pack(3, t1, t2, t3)));
}
}
}
From 74639da997d5f2e53f001d9f256be86ceee901f5 Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Sat, 9 Oct 2021 13:49:02 +0200
Subject: [PATCH] OCCT: port FreeCAD sources to version 7.6 SMESH is not yet
ported Although FreeCAD code compiles with OCCT 7.6 it doesn't work at the
moment
---
src/Mod/Drawing/App/DrawingExport.cpp | 11 ++-
src/Mod/Drawing/App/ProjectionAlgos.cpp | 3 -
src/Mod/Import/App/ImpExpDxf.cpp | 9 +-
.../App/GeomPlate/CurveConstraintPyImp.cpp | 41 +++++++++-
src/Mod/Part/App/Geometry.cpp | 7 +-
src/Mod/Part/App/PartFeatures.cpp | 22 ++---
src/Mod/Part/App/TopoShape.cpp | 82 ++++++-------------
src/Mod/Part/App/TopoShapeFacePyImp.cpp | 10 +++
src/Mod/Part/App/TopoShapeWirePyImp.cpp | 6 +-
src/Mod/Part/Gui/TaskCheckGeometry.cpp | 6 +-
src/Mod/Part/Gui/ViewProviderExt.cpp | 17 ++++
src/Mod/Path/App/AppPathPy.cpp | 5 +-
src/Mod/TechDraw/App/Geometry.cpp | 12 ++-
13 files changed, 138 insertions(+), 93 deletions(-)
diff --git a/src/Mod/Drawing/App/DrawingExport.cpp b/src/Mod/Drawing/App/DrawingExport.cpp
index b87891ed507..7572be417cf 100644
--- a/src/Mod/Drawing/App/DrawingExport.cpp
+++ b/src/Mod/Drawing/App/DrawingExport.cpp
@@ -64,10 +64,7 @@
#include <BRep_Tool.hxx>
#include <BRepAdaptor_CompCurve.hxx>
-#include <BRepAdaptor_HCompCurve.hxx>
#include <Approx_Curve3d.hxx>
-#include <BRepAdaptor_HCurve.hxx>
-#include <BRepAdaptor_HCurve.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_BezierCurve.hxx>
#include <GeomConvert_BSplineCurveToBezierCurve.hxx>
@@ -75,11 +72,19 @@
#include <Geom2d_BSplineCurve.hxx>
#include <BRepLProp_CLProps.hxx>
#include <Standard_Failure.hxx>
+#include <Standard_Version.hxx>
+#if OCC_VERSION_HEX < 0x070600
+#include <BRepAdaptor_HCurve.hxx>
+#endif
#include "DrawingExport.h"
#include <Base/Tools.h>
#include <Base/Vector3D.h>
+#if OCC_VERSION_HEX >= 0x070600
+using BRepAdaptor_HCurve = BRepAdaptor_Curve;
+#endif
+
using namespace Drawing;
using namespace std;
diff --git a/src/Mod/Drawing/App/ProjectionAlgos.cpp b/src/Mod/Drawing/App/ProjectionAlgos.cpp
index 9afae7e9c00..da03d490579 100644
--- a/src/Mod/Drawing/App/ProjectionAlgos.cpp
+++ b/src/Mod/Drawing/App/ProjectionAlgos.cpp
@@ -61,10 +61,7 @@
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRepLib.hxx>
#include <BRepAdaptor_CompCurve.hxx>
-#include <BRepAdaptor_HCompCurve.hxx>
#include <Approx_Curve3d.hxx>
-#include <BRepAdaptor_HCurve.hxx>
-#include <BRepAdaptor_HCurve.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_BezierCurve.hxx>
#include <GeomConvert_BSplineCurveToBezierCurve.hxx>
diff --git a/src/Mod/Import/App/ImpExpDxf.cpp b/src/Mod/Import/App/ImpExpDxf.cpp
index 09827bd9285..dcd88ef1384 100644
--- a/src/Mod/Import/App/ImpExpDxf.cpp
+++ b/src/Mod/Import/App/ImpExpDxf.cpp
@@ -29,7 +29,6 @@
#include <Approx_Curve3d.hxx>
#include <BRepAdaptor_Curve.hxx>
-#include <BRepAdaptor_HCurve.hxx>
#include <BRep_Builder.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
@@ -47,6 +46,7 @@
#include <gp_Pnt.hxx>
#include <gp_Dir.hxx>
#include <gp_Vec.hxx>
+#include <Standard_Version.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
@@ -55,6 +55,9 @@
#include <TopExp_Explorer.hxx>
#include <TopoDS_Edge.hxx>
#include <TColgp_Array1OfPnt.hxx>
+#if OCC_VERSION_HEX < 0x070600
+#include <BRepAdaptor_HCurve.hxx>
+#endif
#include <Base/Console.h>
#include <Base/Parameter.h>
@@ -68,6 +71,10 @@
using namespace Import;
+#if OCC_VERSION_HEX >= 0x070600
+using BRepAdaptor_HCurve = BRepAdaptor_Curve;
+#endif
+
//******************************************************************************
// reading
diff --git a/src/Mod/Part/App/GeomPlate/CurveConstraintPyImp.cpp b/src/Mod/Part/App/GeomPlate/CurveConstraintPyImp.cpp
index 3271f3651a8..b63227d5374 100644
--- a/src/Mod/Part/App/GeomPlate/CurveConstraintPyImp.cpp
+++ b/src/Mod/Part/App/GeomPlate/CurveConstraintPyImp.cpp
@@ -24,10 +24,13 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <GeomAdaptor_Curve.hxx>
-# include <GeomAdaptor_HCurve.hxx>
# include <Geom2dAdaptor_Curve.hxx>
-# include <Geom2dAdaptor_HCurve.hxx>
# include <Standard_Failure.hxx>
+# include <Standard_Version.hxx>
+# if OCC_VERSION_HEX < 0x070600
+# include <GeomAdaptor_HCurve.hxx>
+# include <Geom2dAdaptor_HCurve.hxx>
+# endif
#endif
#include "GeomPlate/CurveConstraintPy.h"
@@ -76,6 +79,16 @@ int CurveConstraintPy::PyInit(PyObject* args, PyObject* kwds)
return -1;
}
+#if OCC_VERSION_HEX >= 0x070600
+ Handle(Adaptor3d_Curve) hCurve;
+ if (curve->getTypeId().isDerivedFrom(GeomTrimmedCurve::getClassTypeId())) {
+ GeomTrimmedCurve* trim = static_cast<GeomTrimmedCurve*>(curve);
+ hCurve = new GeomAdaptor_Curve(handle, trim->getFirstParameter(), trim->getLastParameter());
+ }
+ else {
+ hCurve = new GeomAdaptor_Curve(handle);
+ }
+#else
Handle(Adaptor3d_HCurve) hCurve;
if (curve->getTypeId().isDerivedFrom(GeomTrimmedCurve::getClassTypeId())) {
GeomTrimmedCurve* trim = static_cast<GeomTrimmedCurve*>(curve);
@@ -86,6 +99,7 @@ int CurveConstraintPy::PyInit(PyObject* args, PyObject* kwds)
GeomAdaptor_Curve adapt(handle);
hCurve = new GeomAdaptor_HCurve(adapt);
}
+#endif
ptr.reset(new GeomPlate_CurveConstraint(hCurve, order, nbPts, tolDist, tolAng, tolCurv));
}
@@ -212,11 +226,15 @@ PyObject* CurveConstraintPy::curve3d(PyObject *args)
return nullptr;
try {
- Handle(Adaptor3d_HCurve) hAdapt = getGeomPlate_CurveConstraintPtr()->Curve3d();
+ auto hAdapt = getGeomPlate_CurveConstraintPtr()->Curve3d();
if (hAdapt.IsNull())
Py_Return;
+#if OCC_VERSION_HEX >= 0x070600
+ const Adaptor3d_Curve& a3d = *hAdapt;
+#else
const Adaptor3d_Curve& a3d = hAdapt->Curve();
+#endif
std::unique_ptr<GeomCurve> ptr(Part::makeFromCurveAdaptor(a3d));
return ptr->getPyObject();
}
@@ -282,6 +300,16 @@ PyObject* CurveConstraintPy::setProjectedCurve(PyObject *args)
return nullptr;
}
+#if OCC_VERSION_HEX >= 0x070600
+ Handle(Adaptor2d_Curve2d) hCurve;
+ if (handle->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
+ Handle(Geom2d_TrimmedCurve) aTC (Handle(Geom2d_TrimmedCurve)::DownCast (handle));
+ hCurve = new Geom2dAdaptor_Curve(handle, aTC->FirstParameter(), aTC->LastParameter());
+ }
+ else {
+ hCurve = new Geom2dAdaptor_Curve(handle);
+ }
+#else
Handle(Adaptor2d_HCurve2d) hCurve;
if (handle->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
Handle(Geom2d_TrimmedCurve) aTC (Handle(Geom2d_TrimmedCurve)::DownCast (handle));
@@ -292,6 +320,7 @@ PyObject* CurveConstraintPy::setProjectedCurve(PyObject *args)
Geom2dAdaptor_Curve adapt(handle);
hCurve = new Geom2dAdaptor_HCurve(adapt);
}
+#endif
getGeomPlate_CurveConstraintPtr()->SetProjectedCurve(hCurve, tolU, tolV);
Py_Return;
@@ -308,11 +337,15 @@ PyObject* CurveConstraintPy::projectedCurve(PyObject *args)
return nullptr;
try {
- Handle(Adaptor2d_HCurve2d) hAdapt = getGeomPlate_CurveConstraintPtr()->ProjectedCurve();
+ auto hAdapt = getGeomPlate_CurveConstraintPtr()->ProjectedCurve();
if (hAdapt.IsNull())
Py_Return;
+#if OCC_VERSION_HEX >= 0x070600
+ const Adaptor2d_Curve2d& a2d = *hAdapt;
+#else
const Adaptor2d_Curve2d& a2d = hAdapt->Curve2d();
+#endif
std::unique_ptr<Geom2dCurve> ptr(Part::makeFromCurveAdaptor2d(a2d));
return ptr->getPyObject();
}
diff --git a/src/Mod/Part/App/Geometry.cpp b/src/Mod/Part/App/Geometry.cpp
index e6d6396ca94..1d1d67d4f01 100644
--- a/src/Mod/Part/App/Geometry.cpp
+++ b/src/Mod/Part/App/Geometry.cpp
@@ -51,7 +51,6 @@
# include <Geom_RectangularTrimmedSurface.hxx>
# include <Geom_SurfaceOfRevolution.hxx>
# include <Geom_SurfaceOfLinearExtrusion.hxx>
-# include <GeomAdaptor_HCurve.hxx>
# include <GeomAPI_Interpolate.hxx>
# include <GeomConvert.hxx>
# include <GeomConvert_CompCurveToBSplineCurve.hxx>
@@ -101,6 +100,9 @@
# include <GeomAPI_ExtremaCurveCurve.hxx>
# include <ShapeConstruct_Curve.hxx>
# include <LProp_NotDefined.hxx>
+# if OCC_VERSION_HEX < 0x070600
+# include <GeomAdaptor_HCurve.hxx>
+# endif
# include <ctime>
# include <cmath>
@@ -144,6 +146,9 @@
#include "Geometry.h"
+#if OCC_VERSION_HEX >= 0x070600
+using GeomAdaptor_HCurve = GeomAdaptor_Curve;
+#endif
using namespace Part;
diff --git a/src/Mod/Part/App/PartFeatures.cpp b/src/Mod/Part/App/PartFeatures.cpp
index 2dc503bdf21..4d9e1fc0f99 100644
--- a/src/Mod/Part/App/PartFeatures.cpp
+++ b/src/Mod/Part/App/PartFeatures.cpp
@@ -25,9 +25,7 @@
#ifndef _PreComp_
# include <BRepFill.hxx>
# include <BRepAdaptor_Curve.hxx>
-# include <BRepAdaptor_HCurve.hxx>
# include <BRepAdaptor_CompCurve.hxx>
-# include <BRepAdaptor_HCompCurve.hxx>
# include <BRepLib_MakeWire.hxx>
# include <Geom_BSplineSurface.hxx>
# include <TopoDS.hxx>
@@ -43,7 +41,7 @@
# include <TopExp_Explorer.hxx>
# include <TopoDS.hxx>
# include <Precision.hxx>
-# include <Adaptor3d_HCurve.hxx>
+# include <memory>
#endif
@@ -170,22 +168,18 @@ App::DocumentObjectExecReturn *RuledSurface::execute(void)
if (Orientation.getValue() == 0) {
// Automatic
- Handle(Adaptor3d_HCurve) a1;
- Handle(Adaptor3d_HCurve) a2;
+ std::unique_ptr<Adaptor3d_Curve> a1;
+ std::unique_ptr<Adaptor3d_Curve> a2;
if (!isWire) {
- BRepAdaptor_Curve adapt1(TopoDS::Edge(S1));
- BRepAdaptor_Curve adapt2(TopoDS::Edge(S2));
- a1 = new BRepAdaptor_HCurve(adapt1);
- a2 = new BRepAdaptor_HCurve(adapt2);
+ a1 = std::make_unique<BRepAdaptor_Curve>(TopoDS::Edge(S1));
+ a2 = std::make_unique<BRepAdaptor_Curve>(TopoDS::Edge(S2));
}
else {
- BRepAdaptor_CompCurve adapt1(TopoDS::Wire(S1));
- BRepAdaptor_CompCurve adapt2(TopoDS::Wire(S2));
- a1 = new BRepAdaptor_HCompCurve(adapt1);
- a2 = new BRepAdaptor_HCompCurve(adapt2);
+ a1 = std::make_unique<BRepAdaptor_CompCurve>(TopoDS::Wire(S1));
+ a2 = std::make_unique<BRepAdaptor_CompCurve>(TopoDS::Wire(S2));
}
- if (!a1.IsNull() && !a2.IsNull()) {
+ if (a1 && a2) {
// get end points of 1st curve
Standard_Real first, last;
first = a1->FirstParameter();
diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp
index 05341de3d66..b7617a3943e 100644
--- a/src/Mod/Part/App/TopoShape.cpp
+++ b/src/Mod/Part/App/TopoShape.cpp
@@ -38,8 +38,6 @@
# include <BRep_Tool.hxx>
# include <BRepAdaptor_Curve.hxx>
# include <BRepAdaptor_CompCurve.hxx>
-# include <BRepAdaptor_HCurve.hxx>
-# include <BRepAdaptor_HCompCurve.hxx>
# include <BRepAdaptor_Surface.hxx>
# include <BRepAlgoAPI_Common.hxx>
# include <BRepAlgoAPI_Cut.hxx>
@@ -186,6 +184,12 @@
#if OCC_VERSION_HEX >= 0x070300
# include <BRepAlgoAPI_Defeaturing.hxx>
#endif
+
+#if OCC_VERSION_HEX < 0x070600
+# include <BRepAdaptor_HCurve.hxx>
+# include <BRepAdaptor_HCompCurve.hxx>
+#endif
+
#endif // _PreComp_
#include <boost/algorithm/string/predicate.hpp>
@@ -2133,12 +2137,20 @@ TopoDS_Shape TopoShape::makeTube(double radius, double tol, int cont, int maxdeg
if (this->_Shape.IsNull())
Standard_Failure::Raise("Cannot sweep along empty spine");
+#if OCC_VERSION_HEX >= 0x070600
+ Handle(Adaptor3d_Curve) myPath;
+ if (this->_Shape.ShapeType() == TopAbs_EDGE) {
+ const TopoDS_Edge& path_edge = TopoDS::Edge(this->_Shape);
+ myPath = new BRepAdaptor_Curve(path_edge);
+ }
+#else
Handle(Adaptor3d_HCurve) myPath;
if (this->_Shape.ShapeType() == TopAbs_EDGE) {
const TopoDS_Edge& path_edge = TopoDS::Edge(this->_Shape);
BRepAdaptor_Curve path_adapt(path_edge);
myPath = new BRepAdaptor_HCurve(path_adapt);
}
+#endif
//else if (this->_Shape.ShapeType() == TopAbs_WIRE) {
// const TopoDS_Wire& path_wire = TopoDS::Wire(this->_Shape);
// BRepAdaptor_CompCurve path_adapt(path_wire);
@@ -3777,72 +3789,32 @@ void TopoShape::getLinesFromSubElement(const Data::Segment* element,
for(TopExp_Explorer exp(shape,TopAbs_EDGE);exp.More();exp.Next()) {
TopoDS_Edge aEdge = TopoDS::Edge(exp.Current());
- TopLoc_Location aLoc;
- Handle(Poly_Polygon3D) aPoly = BRep_Tool::Polygon3D(aEdge, aLoc);
+ std::vector<gp_Pnt> points;
- gp_Trsf myTransf;
- Standard_Integer nbNodesInFace;
-
- auto line_start = vertices.size();
-
- // triangulation succeeded?
- if (!aPoly.IsNull()) {
- if (!aLoc.IsIdentity()) {
- myTransf = aLoc.Transformation();
- }
- nbNodesInFace = aPoly->NbNodes();
-
- const TColgp_Array1OfPnt& Nodes = aPoly->Nodes();
-
- gp_Pnt V;
- for (Standard_Integer i=0;i < nbNodesInFace;i++) {
- V = Nodes(i+1);
- V.Transform(myTransf);
- vertices.emplace_back(V.X(),V.Y(),V.Z());
- }
- }
- else {
+ if (!Tools::getPolygon3D(aEdge, points)) {
// the edge has not its own triangulation, but then a face the edge is attached to
// must provide this triangulation
// Look for one face in our map (it doesn't care which one we take)
int index = edge2Face.FindIndex(aEdge);
- if(!index)
+ if (index < 1)
continue;
const auto &faces = edge2Face.FindFromIndex(index);
- if(!faces.Extent())
+ if (faces.Extent() == 0)
continue;
const TopoDS_Face& aFace = TopoDS::Face(faces.First());
- // take the face's triangulation instead
- Handle(Poly_Triangulation) aPolyTria = BRep_Tool::Triangulation(aFace,aLoc);
- if (!aLoc.IsIdentity()) {
- myTransf = aLoc.Transformation();
- }
-
- if (aPolyTria.IsNull()) break;
-
- // this holds the indices of the edge's triangulation to the actual points
- Handle(Poly_PolygonOnTriangulation) aPoly = BRep_Tool::PolygonOnTriangulation(aEdge, aPolyTria, aLoc);
- if (aPoly.IsNull())
- continue; // polygon does not exist
-
- // getting size and create the array
- nbNodesInFace = aPoly->NbNodes();
-
- const TColStd_Array1OfInteger& indices = aPoly->Nodes();
- const TColgp_Array1OfPnt& Nodes = aPolyTria->Nodes();
-
- gp_Pnt V;
- // go through the index array
- for (Standard_Integer i=indices.Lower();i <= indices.Upper();i++) {
- V = Nodes(indices(i));
- V.Transform(myTransf);
- vertices.emplace_back(V.X(),V.Y(),V.Z());
- }
+ if (!Part::Tools::getPolygonOnTriangulation(aEdge, aFace, points))
+ continue;
}
- if(line_start+1 < vertices.size()) {
+ auto line_start = vertices.size();
+ vertices.reserve(vertices.size() + points.size());
+ std::for_each(points.begin(), points.end(), [&vertices](const gp_Pnt& p) {
+ vertices.push_back(Base::convertTo<Base::Vector3d>(p));
+ });
+
+ if (line_start+1 < vertices.size()) {
lines.emplace_back();
lines.back().I1 = line_start;
lines.back().I2 = vertices.size()-1;
diff --git a/src/Mod/Part/App/TopoShapeFacePyImp.cpp b/src/Mod/Part/App/TopoShapeFacePyImp.cpp
index ea6cd98bdf4..63e8bead74d 100644
--- a/src/Mod/Part/App/TopoShapeFacePyImp.cpp
+++ b/src/Mod/Part/App/TopoShapeFacePyImp.cpp
@@ -493,6 +493,15 @@ PyObject* TopoShapeFacePy::getUVNodes(PyObject *args)
return Py::new_reference_to(list);
}
+#if OCC_VERSION_HEX >= 0x070600
+ for (int i=1; i<=mesh->NbNodes(); i++) {
+ gp_Pnt2d pt2d = mesh->UVNode(i);
+ Py::Tuple uv(2);
+ uv.setItem(0, Py::Float(pt2d.X()));
+ uv.setItem(1, Py::Float(pt2d.Y()));
+ list.append(uv);
+ }
+#else
const TColgp_Array1OfPnt2d& aNodesUV = mesh->UVNodes();
for (int i=aNodesUV.Lower(); i<=aNodesUV.Upper(); i++) {
gp_Pnt2d pt2d = aNodesUV(i);
@@ -501,6 +510,7 @@ PyObject* TopoShapeFacePy::getUVNodes(PyObject *args)
uv.setItem(1, Py::Float(pt2d.Y()));
list.append(uv);
}
+#endif
return Py::new_reference_to(list);
}
diff --git a/src/Mod/Part/App/TopoShapeWirePyImp.cpp b/src/Mod/Part/App/TopoShapeWirePyImp.cpp
index 95c1aff6814..a1f32d6d03c 100644
--- a/src/Mod/Part/App/TopoShapeWirePyImp.cpp
+++ b/src/Mod/Part/App/TopoShapeWirePyImp.cpp
@@ -344,9 +344,9 @@ PyObject* TopoShapeWirePy::approximate(PyObject *args, PyObject *kwds)
return 0;
try {
BRepAdaptor_CompCurve adapt(TopoDS::Wire(getTopoShapePtr()->getShape()));
- Handle(Adaptor3d_HCurve) hcurve = adapt.Trim(adapt.FirstParameter(),
- adapt.LastParameter(),
- tol2d);
+ auto hcurve = adapt.Trim(adapt.FirstParameter(),
+ adapt.LastParameter(),
+ tol2d);
Approx_Curve3d approx(hcurve, tol3d, GeomAbs_C0, maxseg, maxdeg);
if (approx.IsDone()) {
return new BSplineCurvePy(new GeomBSplineCurve(approx.Curve()));
diff --git a/src/Mod/Part/Gui/TaskCheckGeometry.cpp b/src/Mod/Part/Gui/TaskCheckGeometry.cpp
index 5de7c169205..aaef13d9d07 100644
--- a/src/Mod/Part/Gui/TaskCheckGeometry.cpp
+++ b/src/Mod/Part/Gui/TaskCheckGeometry.cpp
@@ -711,8 +711,10 @@ int TaskCheckGeometryResults::goBOPSingleCheck(const TopoDS_Shape& shapeIn, Resu
#if OCC_VERSION_HEX >= 0x060900
#if OCC_VERSION_HEX < 0x070500
BOPCheck.SetProgressIndicator(theProgress);
-#else
+#elif OCC_VERSION_HEX < 0x070600
BOPCheck.SetProgressIndicator(theScope);
+#else
+ Q_UNUSED(theScope)
#endif // 0x070500
#else
Q_UNUSED(theProgress);
@@ -740,7 +742,7 @@ int TaskCheckGeometryResults::goBOPSingleCheck(const TopoDS_Shape& shapeIn, Resu
Base::TimeInfo start_time;
#endif
-BOPCheck.Perform();
+ BOPCheck.Perform();
#ifdef FC_DEBUG
float bopAlgoTime = Base::TimeInfo::diffTimeF(start_time,Base::TimeInfo());
diff --git a/src/Mod/Part/Gui/ViewProviderExt.cpp b/src/Mod/Part/Gui/ViewProviderExt.cpp
index 77cefbe3e08..8a52f1701ba 100644
--- a/src/Mod/Part/Gui/ViewProviderExt.cpp
+++ b/src/Mod/Part/Gui/ViewProviderExt.cpp
@@ -1102,7 +1111,11 @@ void ViewProviderPartExt::updateVisual()
}
// get the 3 points of this triangle
+#if OCC_VERSION_HEX < 0x070600
gp_Pnt V1(Nodes(N1)), V2(Nodes(N2)), V3(Nodes(N3));
+#else
+ gp_Pnt V1(mesh->Node(N1)), V2(mesh->Node(N2)), V3(mesh->Node(N3));
+#endif
// get the 3 normals of this triangle
gp_Vec NV1, NV2, NV3;
@@ -1179,7 +1192,11 @@ void ViewProviderPartExt::updateVisual()
// rare cases where some points are only referenced by the polygon
// but not by any triangle. Thus, we must apply the coordinates to
// make sure that everything is properly set.
+#if OCC_VERSION_HEX < 0x070600
gp_Pnt p(Nodes(nodeIndex));
+#else
+ gp_Pnt p(mesh->Node(nodeIndex));
+#endif
if (!identity)
p.Transform(myTransf);
verts[index].setValue((float)(p.X()),(float)(p.Y()),(float)(p.Z()));
diff --git a/src/Mod/Path/App/AppPathPy.cpp b/src/Mod/Path/App/AppPathPy.cpp
index 6e0c72d2f53..ce912b44749 100644
--- a/src/Mod/Path/App/AppPathPy.cpp
+++ b/src/Mod/Path/App/AppPathPy.cpp
@@ -49,10 +49,7 @@
#include <TopExp_Explorer.hxx>
#include <gp_Lin.hxx>
#include <BRep_Tool.hxx>
-#include <BRepAdaptor_CompCurve.hxx>
-#include <BRepAdaptor_HCompCurve.hxx>
-#include <Approx_Curve3d.hxx>
-#include <BRepAdaptor_HCurve.hxx>
+#include <BRepAdaptor_Curve.hxx>
#include "CommandPy.h"
#include "PathPy.h"
diff --git a/src/Mod/TechDraw/App/Geometry.cpp b/src/Mod/TechDraw/App/Geometry.cpp
index b6c36371377..59a92d7e51b 100644
--- a/src/Mod/TechDraw/App/Geometry.cpp
+++ b/src/Mod/TechDraw/App/Geometry.cpp
@@ -28,13 +28,13 @@
#include <BRepAdaptor_Curve.hxx>
#include <BRep_Tool.hxx>
#include <BRepTools.hxx>
-#include <BRepAdaptor_HCurve.hxx>
#include <BRepLib.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
+#include <BRepLProp_CLProps.hxx>
#include <Precision.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <gce_MakeCirc.hxx>
@@ -58,14 +58,16 @@
#include <GeomLProp_CLProps.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
#include <Poly_Polygon3D.hxx>
+#include <Standard_Version.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TColgp_Array1OfPnt.hxx>
-#include <BRepLProp_CLProps.hxx>
-
+#if OCC_VERSION_HEX < 0x070600
+#include <BRepAdaptor_HCurve.hxx>
+#endif
#include <cmath>
#endif // #ifndef _PreComp_
@@ -86,6 +88,10 @@
using namespace TechDraw;
using namespace std;
+#if OCC_VERSION_HEX >= 0x070600
+using BRepAdaptor_HCurve = BRepAdaptor_Curve;
+#endif
+
#define GEOMETRYEDGE 0
#define COSMETICEDGE 1
#define CENTERLINE 2
diff --git a/src/Mod/Part/Gui/ViewProviderExt.cpp b/src/Mod/Part/Gui/ViewProviderExt.cpp
index 77cefbe3e0..8a52f1701b 100644
--- a/src/Mod/Part/Gui/ViewProviderExt.cpp
+++ b/src/Mod/Part/Gui/ViewProviderExt.cpp
@@ -1154,16 +1154,25 @@
// cycling through the poly mesh
+#if OCC_VERSION_HEX < 0x070600
const Poly_Array1OfTriangle& Triangles = mesh->Triangles();
const TColgp_Array1OfPnt& Nodes = mesh->Nodes();
TColgp_Array1OfDir Normals (Nodes.Lower(), Nodes.Upper());
+#else
+ int numNodes = mesh->NbNodes();
+ TColgp_Array1OfDir Normals (1, numNodes);
+#endif
if (NormalsFromUV)
getNormals(actFace, mesh, Normals);
for (int g=1;g<=nbTriInFace;g++) {
// Get the triangle
Standard_Integer N1,N2,N3;
+#if OCC_VERSION_HEX < 0x070600
Triangles(g).Get(N1,N2,N3);
+#else
+ mesh->Triangle(g).Get(N1,N2,N3);
+#endif
// change orientation of the triangle if the face is reversed
if ( orient != TopAbs_FORWARD ) {
From c9d17ebde2400f83d1e1e799bdb0a7f85a0da96d Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Fri, 8 Oct 2021 12:41:07 +0200
Subject: [PATCH] Part: add convenience functions to retrieve triangulation of
a face or edge
---
src/Mod/Part/App/Tools.cpp | 170 ++++++++++++++++++++++++++++++++++++-
src/Mod/Part/App/Tools.h | 31 ++++++-
2 files changed, 198 insertions(+), 3 deletions(-)
diff --git a/src/Mod/Part/App/Tools.cpp b/src/Mod/Part/App/Tools.cpp
index b02c0560453..c0e59445089 100644
--- a/src/Mod/Part/App/Tools.cpp
+++ b/src/Mod/Part/App/Tools.cpp
@@ -25,25 +25,31 @@
# include <cassert>
# include <gp_Pln.hxx>
# include <gp_Lin.hxx>
-# include <Adaptor3d_HCurveOnSurface.hxx>
+# include <BRep_Tool.hxx>
# include <Geom_BSplineSurface.hxx>
# include <Geom_Plane.hxx>
-# include <GeomAdaptor_HCurve.hxx>
# include <GeomAPI_IntSS.hxx>
# include <Geom_Line.hxx>
# include <Geom_Point.hxx>
+# include <GeomAdaptor_Curve.hxx>
# include <GeomPlate_BuildPlateSurface.hxx>
# include <GeomPlate_CurveConstraint.hxx>
# include <GeomPlate_MakeApprox.hxx>
# include <GeomPlate_PlateG0Criterion.hxx>
# include <GeomPlate_PointConstraint.hxx>
+# include <Poly_Triangulation.hxx>
# include <Precision.hxx>
# include <Standard_Mutex.hxx>
# include <Standard_TypeMismatch.hxx>
+# include <Standard_Version.hxx>
# include <TColStd_ListOfTransient.hxx>
# include <TColStd_ListIteratorOfListOfTransient.hxx>
# include <TColgp_SequenceOfXY.hxx>
# include <TColgp_SequenceOfXYZ.hxx>
+# if OCC_VERSION_HEX < 0x070600
+# include <Adaptor3d_HCurveOnSurface.hxx>
+# include <GeomAdaptor_HCurve.hxx>
+# endif
#endif
#include <Base/Vector3D.h>
@@ -138,6 +144,20 @@ Part::Tools::makeSurface(const TColStd_ListOfTransient &theBoundaries,
assert (0);
Standard_ConstructionError::Raise ("Tools::makeSurface()");
}
+#if OCC_VERSION_HEX >= 0x070600
+ else if (aCur->IsKind (STANDARD_TYPE (Adaptor3d_CurveOnSurface))) {
+ //G1 constraint
+ Handle(Adaptor3d_CurveOnSurface) aHCOS (Handle(Adaptor3d_CurveOnSurface)::DownCast (aCur));
+ Handle (GeomPlate_CurveConstraint) aConst = new GeomPlate_CurveConstraint (aHCOS, 1 /*GeomAbs_G1*/,aNbPnts, aTol3d, anAngTol, aCurvTol);
+ aPlateBuilder.Add (aConst);
+ }
+ else if (aCur->IsKind (STANDARD_TYPE (GeomAdaptor_Curve))) {
+ //G0 constraint
+ Handle(GeomAdaptor_Curve) aHC (Handle(GeomAdaptor_Curve)::DownCast (aCur));
+ Handle (GeomPlate_CurveConstraint) aConst = new GeomPlate_CurveConstraint (aHC, 0 /*GeomAbs_G0*/, aNbPnts, aTol3d);
+ aPlateBuilder.Add (aConst);
+ }
+#else
else if (aCur->IsKind (STANDARD_TYPE (Adaptor3d_HCurveOnSurface))) {
//G1 constraint
Handle(Adaptor3d_HCurveOnSurface) aHCOS (Handle(Adaptor3d_HCurveOnSurface)::DownCast (aCur));
@@ -150,6 +170,7 @@ Part::Tools::makeSurface(const TColStd_ListOfTransient &theBoundaries,
Handle (GeomPlate_CurveConstraint) aConst = new GeomPlate_CurveConstraint (aHC, 0 /*GeomAbs_G0*/, aNbPnts, aTol3d);
aPlateBuilder.Add (aConst);
}
+#endif
else if (aCur->IsKind (STANDARD_TYPE (Geom_Point))) {
//Point constraint
Handle(Geom_Point) aGP (Handle(Geom_Point)::DownCast (aCur));
@@ -190,3 +211,148 @@ Part::Tools::makeSurface(const TColStd_ListOfTransient &theBoundaries,
return aRes;
}
+
+bool Part::Tools::getTriangulation(const TopoDS_Face& face, std::vector<gp_Pnt>& points, std::vector<Poly_Triangle>& facets)
+{
+ TopLoc_Location loc;
+ Handle(Poly_Triangulation) hTria = BRep_Tool::Triangulation(face, loc);
+ if (hTria.IsNull())
+ return false;
+
+ // getting the transformation of the face
+ gp_Trsf transf;
+ bool identity = true;
+ if (!loc.IsIdentity()) {
+ identity = false;
+ transf = loc.Transformation();
+ }
+
+ // check orientation
+ TopAbs_Orientation orient = face.Orientation();
+
+ Standard_Integer nbNodes = hTria->NbNodes();
+ Standard_Integer nbTriangles = hTria->NbTriangles();
+#if OCC_VERSION_HEX < 0x070600
+ const TColgp_Array1OfPnt& nodes = hTria->Nodes();
+ const Poly_Array1OfTriangle& triangles = hTria->Triangles();
+#endif
+
+ points.reserve(nbNodes);
+ facets.reserve(nbTriangles);
+
+ // cycling through the poly mesh
+ //
+ for (int i = 1; i <= nbNodes; i++) {
+#if OCC_VERSION_HEX < 0x070600
+ gp_Pnt p = nodes(i);
+#else
+ gp_Pnt p = hTria->Node(i);
+#endif
+
+ // transform the vertices to the location of the face
+ if (!identity) {
+ p.Transform(transf);
+ }
+
+ points.push_back(p);
+ }
+
+ for (int i = 1; i <= nbTriangles; i++) {
+ // Get the triangle
+ Standard_Integer n1,n2,n3;
+#if OCC_VERSION_HEX < 0x070600
+ triangles(i).Get(n1, n2, n3);
+#else
+ hTria->Triangle(i).Get(n1, n2, n3);
+#endif
+ --n1; --n2; --n3;
+
+ // change orientation of the triangles
+ if (orient != TopAbs_FORWARD) {
+ std::swap(n1, n2);
+ }
+
+ facets.emplace_back(n1, n2, n3);
+ }
+
+ return true;
+}
+
+bool Part::Tools::getPolygonOnTriangulation(const TopoDS_Edge& edge, const TopoDS_Face& face, std::vector<gp_Pnt>& points)
+{
+ TopLoc_Location loc;
+ Handle(Poly_Triangulation) hTria = BRep_Tool::Triangulation(face, loc);
+ if (hTria.IsNull())
+ return false;
+
+ // this holds the indices of the edge's triangulation to the actual points
+ Handle(Poly_PolygonOnTriangulation) hPoly = BRep_Tool::PolygonOnTriangulation(edge, hTria, loc);
+ if (hPoly.IsNull())
+ return false;
+
+ // getting the transformation of the edge
+ gp_Trsf transf;
+ bool identity = true;
+ if (!loc.IsIdentity()) {
+ identity = false;
+ transf = loc.Transformation();
+ }
+
+ // getting size and create the array
+ Standard_Integer nbNodes = hPoly->NbNodes();
+ points.reserve(nbNodes);
+ const TColStd_Array1OfInteger& indices = hPoly->Nodes();
+#if OCC_VERSION_HEX < 0x070600
+ const TColgp_Array1OfPnt& Nodes = hTria->Nodes();
+#endif
+
+ // go through the index array
+ for (Standard_Integer i = indices.Lower(); i <= indices.Upper(); i++) {
+#if OCC_VERSION_HEX < 0x070600
+ gp_Pnt p = Nodes(indices(i));
+#else
+ gp_Pnt p = hTria->Node(indices(i));
+#endif
+ if (!identity) {
+ p.Transform(transf);
+ }
+
+ points.push_back(p);
+ }
+
+ return true;
+}
+
+bool Part::Tools::getPolygon3D(const TopoDS_Edge& edge, std::vector<gp_Pnt>& points)
+{
+ TopLoc_Location loc;
+ Handle(Poly_Polygon3D) hPoly = BRep_Tool::Polygon3D(edge, loc);
+ if (hPoly.IsNull())
+ return false;
+
+ // getting the transformation of the edge
+ gp_Trsf transf;
+ bool identity = true;
+ if (!loc.IsIdentity()) {
+ identity = false;
+ transf = loc.Transformation();
+ }
+
+ // getting size and create the array
+ Standard_Integer nbNodes = hPoly->NbNodes();
+ points.reserve(nbNodes);
+ const TColgp_Array1OfPnt& nodes = hPoly->Nodes();
+
+ for (int i = 1; i <= nbNodes; i++) {
+ gp_Pnt p = nodes(i);
+
+ // transform the vertices to the location of the face
+ if (!identity) {
+ p.Transform(transf);
+ }
+
+ points.push_back(p);
+ }
+
+ return true;
+}
diff --git a/src/Mod/Part/App/Tools.h b/src/Mod/Part/App/Tools.h
index a936c352c65..19ecf937fda 100644
--- a/src/Mod/Part/App/Tools.h
+++ b/src/Mod/Part/App/Tools.h
@@ -30,7 +30,11 @@
#include <gp_Dir.hxx>
#include <gp_XYZ.hxx>
#include <Geom_Surface.hxx>
+#include <Poly_Triangle.hxx>
#include <TColStd_ListOfTransient.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <vector>
class gp_Lin;
class gp_Pln;
@@ -104,7 +108,32 @@ class PartExport Tools
const Standard_Integer theNbPnts,
const Standard_Integer theNbIter,
const Standard_Integer theMaxDeg);
-
+ /*!
+ * @brief getTriangulation
+ * The indexes of the triangles are adjusted to the points vector.
+ * @param face
+ * @param points
+ * @param facets
+ * @return true if a triangulation exists or false otherwise
+ */
+ static bool getTriangulation(const TopoDS_Face& face, std::vector<gp_Pnt>& points, std::vector<Poly_Triangle>& facets);
+ /*!
+ * \brief getPolygonOnTriangulation
+ * Get the polygon of edge.
+ * \note \a edge must belong to face.
+ * \param edge
+ * \param face
+ * \param points
+ * \return true if a triangulation exists or false otherwise
+ */
+ static bool getPolygonOnTriangulation(const TopoDS_Edge& edge, const TopoDS_Face& face, std::vector<gp_Pnt>& points);
+ /*!
+ * \brief getPolygon3D
+ * \param edge
+ * \param points
+ * \return true if a polygon exists or false otherwise
+ */
+ static bool getPolygon3D(const TopoDS_Edge& edge, std::vector<gp_Pnt>& points);
};
} //namespace Part
From 442c8d52a1989da8f17d60fafea5b81d79cbf0ab Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Fri, 8 Oct 2021 15:32:19 +0200
Subject: [PATCH] Part: in TopoShape::getDomains use functions of Tools class
---
src/Mod/Part/App/TopoShape.cpp | 56 +++++++++++++++-------------------
1 file changed, 25 insertions(+), 31 deletions(-)
diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp
index 09cfab45bb0..05341de3d66 100644
--- a/src/Mod/Part/App/TopoShape.cpp
+++ b/src/Mod/Part/App/TopoShape.cpp
@@ -3360,46 +3360,40 @@ void TopoShape::getDomains(std::vector<Domain>& domains) const
for (TopExp_Explorer xp(this->_Shape, TopAbs_FACE); xp.More(); xp.Next()) {
TopoDS_Face face = TopoDS::Face(xp.Current());
- TopLoc_Location loc;
- Handle(Poly_Triangulation) theTriangulation = BRep_Tool::Triangulation(face, loc);
- if (theTriangulation.IsNull()) {
+ std::vector<gp_Pnt> points;
+ std::vector<Poly_Triangle> facets;
+ if (!Tools::getTriangulation(face, points, facets)) {
// For a face that cannot be meshed append an empty domain.
// It's important for some algorithms (e.g. color mapping) that the numbers of
// faces and domains match
Domain domain;
domains.push_back(domain);
- continue;
}
+ else {
+ Domain domain;
+ // copy the points
+ domain.points.reserve(points.size());
+ for (const auto& it : points) {
+ Standard_Real X, Y, Z;
+ it.Coord (X, Y, Z);
+ domain.points.emplace_back(X, Y, Z);
+ }
- Domain domain;
- // copy the points
- const TColgp_Array1OfPnt& points = theTriangulation->Nodes();
- domain.points.reserve(points.Length());
- for (int i = 1; i <= points.Length(); i++) {
- gp_Pnt p = points(i);
- p.Transform(loc.Transformation());
- Standard_Real X, Y, Z;
- p.Coord (X, Y, Z);
- domain.points.emplace_back(X, Y, Z);
- }
+ // copy the triangles
+ domain.facets.reserve(facets.size());
+ for (const auto& it : facets) {
+ Standard_Integer N1, N2, N3;
+ it.Get(N1, N2, N3);
+
+ Facet tria;
+ tria.I1 = N1;
+ tria.I2 = N2;
+ tria.I3 = N3;
+ domain.facets.push_back(tria);
+ }
- // copy the triangles
- const TopAbs_Orientation anOrientation = face.Orientation();
- bool flip = (anOrientation == TopAbs_REVERSED);
- const Poly_Array1OfTriangle& faces = theTriangulation->Triangles();
- domain.facets.reserve(faces.Length());
- for (int i = 1; i <= faces.Length(); i++) {
- Standard_Integer N1, N2, N3;
- faces(i).Get(N1, N2, N3);
-
- Facet tria;
- tria.I1 = N1-1; tria.I2 = N2-1; tria.I3 = N3-1;
- if (flip)
- std::swap(tria.I1, tria.I2);
- domain.facets.push_back(tria);
+ domains.push_back(domain);
}
-
- domains.push_back(domain);
}
}
From 8e6dab209ee59be61d83a0ff249283a8809fa917 Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Fri, 8 Oct 2021 12:43:06 +0200
Subject: [PATCH] Part: change TopoShape::exportFaceSet and
TopoShape::exportLineSet to use the functions of the Tools class
---
src/Mod/Part/App/TopoShape.cpp | 141 +++++++--------------------------
1 file changed, 29 insertions(+), 112 deletions(-)
diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp
index 614661594d0..09cfab45bb0 100644
--- a/src/Mod/Part/App/TopoShape.cpp
+++ b/src/Mod/Part/App/TopoShape.cpp
@@ -1097,65 +1097,27 @@ void TopoShape::exportFaceSet(double dev, double ca,
for (ex.Init(this->_Shape, TopAbs_FACE); ex.More(); ex.Next(), index++) {
// get the shape and mesh it
const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
- Standard_Integer nbNodesInFace,nbTriInFace;
+ std::vector<gp_Pnt> points;
+ std::vector<Poly_Triangle> facets;
+ if (!Tools::getTriangulation(aFace, points, facets))
+ continue;
+
std::vector<Base::Vector3f> vertices;
std::vector<int> indices;
+ vertices.resize(points.size());
+ indices.resize(4 * facets.size());
- // doing the meshing and checking the result
- TopLoc_Location aLoc;
- Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
- if (aPoly.IsNull()) continue;
-
- // getting the transformation of the shape/face
- gp_Trsf myTransf;
- Standard_Boolean identity = true;
- if (!aLoc.IsIdentity()) {
- identity = false;
- myTransf = aLoc.Transformation();
+ for (std::size_t i = 0; i < points.size(); i++) {
+ vertices[i] = Base::convertTo<Base::Vector3f>(points[i]);
}
- // getting size and create the array
- nbNodesInFace = aPoly->NbNodes();
- nbTriInFace = aPoly->NbTriangles();
- vertices.resize(nbNodesInFace);
- indices.resize(4*nbTriInFace);
-
- // check orientation
- TopAbs_Orientation orient = aFace.Orientation();
-
- // cycling through the poly mesh
- const Poly_Array1OfTriangle& Triangles = aPoly->Triangles();
- const TColgp_Array1OfPnt& Nodes = aPoly->Nodes();
- for (int i=1;i<=nbTriInFace;i++) {
- // Get the triangle
- Standard_Integer N1,N2,N3;
- Triangles(i).Get(N1,N2,N3);
-
- // change orientation of the triangles
- if (orient != TopAbs_FORWARD) {
- Standard_Integer tmp = N1;
- N1 = N2;
- N2 = tmp;
- }
-
- gp_Pnt V1 = Nodes(N1);
- gp_Pnt V2 = Nodes(N2);
- gp_Pnt V3 = Nodes(N3);
-
- // transform the vertices to the place of the face
- if (!identity) {
- V1.Transform(myTransf);
- V2.Transform(myTransf);
- V3.Transform(myTransf);
- }
-
- vertices[N1-1].Set((float)(V1.X()),(float)(V1.Y()),(float)(V1.Z()));
- vertices[N2-1].Set((float)(V2.X()),(float)(V2.Y()),(float)(V2.Z()));
- vertices[N3-1].Set((float)(V3.X()),(float)(V3.Y()),(float)(V3.Z()));
-
- int j = i - 1;
- N1--; N2--; N3--;
- indices[4*j] = N1; indices[4*j+1] = N2; indices[4*j+2] = N3; indices[4*j+3] = -1;
+ for (std::size_t i = 0; i < facets.size(); i++) {
+ Standard_Integer n1,n2,n3;
+ facets[i].Get(n1, n2, n3);
+ indices[4 * i ] = n1;
+ indices[4 * i + 1] = n2;
+ indices[4 * i + 2] = n3;
+ indices[4 * i + 3] = -1;
}
builder.beginSeparator();
@@ -1170,7 +1132,7 @@ void TopoShape::exportFaceSet(double dev, double ca,
builder.endPoints();
builder.addIndexedFaceSet(indices);
builder.endSeparator();
- } // end of face loop
+ }
}
void TopoShape::exportLineSet(std::ostream& str) const
@@ -1183,72 +1145,27 @@ void TopoShape::exportLineSet(std::ostream& str) const
// build up map edge->face
TopTools_IndexedDataMapOfShapeListOfShape edge2Face;
TopExp::MapShapesAndAncestors(this->_Shape, TopAbs_EDGE, TopAbs_FACE, edge2Face);
- for (int i=0; i<M.Extent(); i++)
- {
- const TopoDS_Edge& aEdge = TopoDS::Edge(M(i+1));
- gp_Trsf myTransf;
- TopLoc_Location aLoc;
-
- // try to triangulate the edge
- Handle(Poly_Polygon3D) aPoly = BRep_Tool::Polygon3D(aEdge, aLoc);
-
- std::vector<Base::Vector3f> vertices;
- Standard_Integer nbNodesInFace;
-
- // triangulation succeeded?
- if (!aPoly.IsNull()) {
- if (!aLoc.IsIdentity()) {
- myTransf = aLoc.Transformation();
- }
- nbNodesInFace = aPoly->NbNodes();
- vertices.resize(nbNodesInFace);
- const TColgp_Array1OfPnt& Nodes = aPoly->Nodes();
+ for (int i=0; i<M.Extent(); i++) {
+ const TopoDS_Edge& aEdge = TopoDS::Edge(M(i+1));
+ std::vector<gp_Pnt> points;
- gp_Pnt V;
- for (Standard_Integer i=0;i < nbNodesInFace;i++) {
- V = Nodes(i+1);
- V.Transform(myTransf);
- vertices[i].Set((float)(V.X()),(float)(V.Y()),(float)(V.Z()));
- }
- }
- else {
+ if (!Tools::getPolygon3D(aEdge, points)) {
// the edge has not its own triangulation, but then a face the edge is attached to
// must provide this triangulation
// Look for one face in our map (it doesn't care which one we take)
const TopoDS_Face& aFace = TopoDS::Face(edge2Face.FindFromKey(aEdge).First());
-
- // take the face's triangulation instead
- Handle(Poly_Triangulation) aPolyTria = BRep_Tool::Triangulation(aFace,aLoc);
- if (!aLoc.IsIdentity()) {
- myTransf = aLoc.Transformation();
- }
-
- if (aPolyTria.IsNull()) break;
-
- // this holds the indices of the edge's triangulation to the actual points
- Handle(Poly_PolygonOnTriangulation) aPoly = BRep_Tool::PolygonOnTriangulation(aEdge, aPolyTria, aLoc);
- if (aPoly.IsNull())
- continue; // polygon does not exist
-
- // getting size and create the array
- nbNodesInFace = aPoly->NbNodes();
- vertices.resize(nbNodesInFace);
-
- const TColStd_Array1OfInteger& indices = aPoly->Nodes();
- const TColgp_Array1OfPnt& Nodes = aPolyTria->Nodes();
-
- gp_Pnt V;
- int pos = 0;
- // go through the index array
- for (Standard_Integer i=indices.Lower();i <= indices.Upper();i++) {
- V = Nodes(indices(i));
- V.Transform(myTransf);
- vertices[pos++].Set((float)(V.X()),(float)(V.Y()),(float)(V.Z()));
- }
+ if (!Tools::getPolygonOnTriangulation(aEdge, aFace, points))
+ continue;
}
+ std::vector<Base::Vector3f> vertices;
+ vertices.reserve(points.size());
+ std::for_each(points.begin(), points.end(), [&vertices](const gp_Pnt& p) {
+ vertices.push_back(Base::convertTo<Base::Vector3f>(p));
+ });
+
builder.addLineSet(vertices, 2, 0, 0, 0);
}
}
From 0f3b5d275070477b7cd2bbfa2dc930135448fb0c Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Fri, 8 Oct 2021 15:29:36 +0200
Subject: [PATCH] Raytracing: in PovTools/LuxTools use functions of Tools class
---
src/Mod/Raytracing/App/LuxTools.cpp | 34 ++---
src/Mod/Raytracing/App/PovTools.cpp | 220 ++++++----------------------
src/Mod/Raytracing/App/PovTools.h | 3 -
3 files changed, 62 insertions(+), 195 deletions(-)
diff --git a/src/Mod/Raytracing/App/LuxTools.cpp b/src/Mod/Raytracing/App/LuxTools.cpp
index 881317f137b..86db2ee16f6 100644
--- a/src/Mod/Raytracing/App/LuxTools.cpp
+++ b/src/Mod/Raytracing/App/LuxTools.cpp
@@ -44,6 +44,7 @@
#include "PovTools.h"
#include "LuxTools.h"
+#include <Mod/Part/App/Tools.h>
using Base::Console;
@@ -95,35 +96,34 @@ void LuxTools::writeShape(std::ostream &out, const char *PartName, const TopoDS_
// get the shape and mesh it
const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
- // this block mesh the face and transfers it in a C array of vertices and face indexes
- Standard_Integer nbNodesInFace,nbTriInFace;
- gp_Vec* vertices=0;
- gp_Vec* vertexnormals=0;
- long* cons=0;
+ std::vector<gp_Pnt> points;
+ std::vector<gp_Vec> vertexnormals;
+ std::vector<Poly_Triangle> facets;
+ if (!Part::Tools::getTriangulation(aFace, points, facets)) {
+ break;
+ }
- PovTools::transferToArray(aFace,&vertices,&vertexnormals,&cons,nbNodesInFace,nbTriInFace);
+ Part::Tools::getPointNormals(points, facets, vertexnormals);
+ Part::Tools::getPointNormals(points, aFace, vertexnormals);
- if (!vertices) break;
// writing vertices
- for (int i=0; i < nbNodesInFace; i++) {
- P << vertices[i].X() << " " << vertices[i].Y() << " " << vertices[i].Z() << " ";
+ for (std::size_t i=0; i < points.size(); i++) {
+ P << points[i].X() << " " << points[i].Y() << " " << points[i].Z() << " ";
}
// writing per vertex normals
- for (int j=0; j < nbNodesInFace; j++) {
+ for (std::size_t j=0; j < vertexnormals.size(); j++) {
N << vertexnormals[j].X() << " " << vertexnormals[j].Y() << " " << vertexnormals[j].Z() << " ";
}
// writing triangle indices
- for (int k=0; k < nbTriInFace; k++) {
- triindices << cons[3*k]+vi << " " << cons[3*k+2]+vi << " " << cons[3*k+1]+vi << " ";
+ for (std::size_t k=0; k < facets.size(); k++) {
+ Standard_Integer n1, n2, n3;
+ facets[k].Get(n1, n2, n3);
+ triindices << n1 + vi << " " << n3 + vi << " " << n2 + vi << " ";
}
- vi = vi + nbNodesInFace;
-
- delete [] vertexnormals;
- delete [] vertices;
- delete [] cons;
+ vi = vi + points.size();
seq.next();
diff --git a/src/Mod/Raytracing/App/PovTools.cpp b/src/Mod/Raytracing/App/PovTools.cpp
index e2d7c1f4d7b..049308c8b9d 100644
--- a/src/Mod/Raytracing/App/PovTools.cpp
+++ b/src/Mod/Raytracing/App/PovTools.cpp
@@ -41,6 +41,7 @@
#include "PovTools.h"
+#include <Mod/Part/App/Tools.h>
using Base::Console;
@@ -242,53 +243,53 @@ void PovTools::writeShape(std::ostream &out, const char *PartName,
// get the shape and mesh it
const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
- // this block mesh the face and transfers it in a C array of vertices and face indexes
- Standard_Integer nbNodesInFace,nbTriInFace;
- gp_Vec* vertices=0;
- gp_Vec* vertexnormals=0;
- long* cons=0;
-
- transferToArray(aFace,&vertices,&vertexnormals,&cons,nbNodesInFace,nbTriInFace);
+ std::vector<gp_Pnt> points;
+ std::vector<gp_Vec> vertexnormals;
+ std::vector<Poly_Triangle> facets;
+ if (!Part::Tools::getTriangulation(aFace, points, facets)) {
+ break;
+ }
+ Part::Tools::getPointNormals(points, facets, vertexnormals);
+ Part::Tools::getPointNormals(points, aFace, vertexnormals);
- if (!vertices) break;
// writing per face header
out << "// face number" << l << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
<< "#declare " << PartName << l << " = mesh2{" << endl
<< " vertex_vectors {" << endl
- << " " << nbNodesInFace << "," << endl;
+ << " " << points.size() << "," << endl;
// writing vertices
- for (int i=0; i < nbNodesInFace; i++) {
- out << " <" << vertices[i].X() << ","
- << vertices[i].Z() << ","
- << vertices[i].Y() << ">,"
- << endl;
+ for (std::size_t i=0; i < points.size(); i++) {
+ out << " <"
+ << points[i].X() << ","
+ << points[i].Z() << ","
+ << points[i].Y() << ">,"
+ << endl;
}
out << " }" << endl
// writing per vertex normals
<< " normal_vectors {" << endl
- << " " << nbNodesInFace << "," << endl;
- for (int j=0; j < nbNodesInFace; j++) {
- out << " <" << vertexnormals[j].X() << ","
- << vertexnormals[j].Z() << ","
- << vertexnormals[j].Y() << ">,"
- << endl;
+ << " " << vertexnormals.size() << "," << endl;
+ for (std::size_t j=0; j < vertexnormals.size(); j++) {
+ out << " <"
+ << vertexnormals[j].X() << ","
+ << vertexnormals[j].Z() << ","
+ << vertexnormals[j].Y() << ">,"
+ << endl;
}
out << " }" << endl
// writing triangle indices
<< " face_indices {" << endl
- << " " << nbTriInFace << "," << endl;
- for (int k=0; k < nbTriInFace; k++) {
- out << " <" << cons[3*k] << ","<< cons[3*k+2] << ","<< cons[3*k+1] << ">," << endl;
+ << " " << facets.size() << "," << endl;
+ for (std::size_t k=0; k < facets.size(); k++) {
+ Standard_Integer n1, n2, n3;
+ facets[k].Get(n1, n2, n3);
+ out << " <" << n1 << ","<< n3 << "," << n2 << ">," << endl;
}
// end of face
out << " }" << endl
<< "} // end of Face"<< l << endl << endl;
- delete [] vertexnormals;
- delete [] vertices;
- delete [] cons;
-
seq.next();
} // end of face loop
@@ -323,167 +324,36 @@ void PovTools::writeShapeCSV(const char *FileName,
Base::SequencerLauncher seq("Writing file", l);
// write the file
- l = 1;
- for (ex.Init(Shape, TopAbs_FACE); ex.More(); ex.Next(),l++) {
+ for (ex.Init(Shape, TopAbs_FACE); ex.More(); ex.Next()) {
// get the shape and mesh it
const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
- // this block mesh the face and transfers it in a C array of vertices and face indexes
- Standard_Integer nbNodesInFace,nbTriInFace;
- gp_Vec* vertices=0;
- gp_Vec* vertexnormals=0;
- long* cons=0;
+ std::vector<gp_Pnt> points;
+ std::vector<gp_Vec> vertexnormals;
+ std::vector<Poly_Triangle> facets;
+ if (!Part::Tools::getTriangulation(aFace, points, facets)) {
+ break;
+ }
- transferToArray(aFace,&vertices,&vertexnormals,&cons,nbNodesInFace,nbTriInFace);
+ Part::Tools::getPointNormals(points, facets, vertexnormals);
+ Part::Tools::getPointNormals(points, aFace, vertexnormals);
- if (!vertices) break;
// writing per face header
// writing vertices
- for (int i=0; i < nbNodesInFace; i++) {
- fout << vertices[i].X() << cSeperator
- << vertices[i].Z() << cSeperator
- << vertices[i].Y() << cSeperator
- << vertexnormals[i].X() * fLength <<cSeperator
- << vertexnormals[i].Z() * fLength <<cSeperator
- << vertexnormals[i].Y() * fLength <<cSeperator
- << endl;
+ for (std::size_t i=0; i < points.size(); i++) {
+ fout << points[i].X() << cSeperator
+ << points[i].Z() << cSeperator
+ << points[i].Y() << cSeperator
+ << vertexnormals[i].X() * fLength << cSeperator
+ << vertexnormals[i].Z() * fLength << cSeperator
+ << vertexnormals[i].Y() * fLength << cSeperator
+ << endl;
}
- delete [] vertexnormals;
- delete [] vertices;
- delete [] cons;
-
seq.next();
} // end of face loop
fout.close();
}
-
-void PovTools::transferToArray(const TopoDS_Face& aFace,gp_Vec** vertices,gp_Vec** vertexnormals, long** cons,int &nbNodesInFace,int &nbTriInFace )
-{
- TopLoc_Location aLoc;
-
- // doing the meshing and checking the result
- //BRepMesh_IncrementalMesh MESH(aFace,fDeflection);
- Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
- if (aPoly.IsNull()) {
- Base::Console().Log("Empty face triangulation\n");
- nbNodesInFace =0;
- nbTriInFace = 0;
- vertices = 0l;
- cons = 0l;
- return;
- }
-
- // getting the transformation of the shape/face
- gp_Trsf myTransf;
- Standard_Boolean identity = true;
- if (!aLoc.IsIdentity()) {
- identity = false;
- myTransf = aLoc.Transformation();
- }
-
- Standard_Integer i;
- // getting size and create the array
- nbNodesInFace = aPoly->NbNodes();
- nbTriInFace = aPoly->NbTriangles();
- *vertices = new gp_Vec[nbNodesInFace];
- *vertexnormals = new gp_Vec[nbNodesInFace];
- for (i=0; i < nbNodesInFace; i++) {
- (*vertexnormals)[i]= gp_Vec(0.0,0.0,0.0);
- }
-
- *cons = new long[3*(nbTriInFace)+1];
-
- // check orientation
- TopAbs_Orientation orient = aFace.Orientation();
-
- // cycling through the poly mesh
- const Poly_Array1OfTriangle& Triangles = aPoly->Triangles();
- const TColgp_Array1OfPnt& Nodes = aPoly->Nodes();
- for (i=1; i<=nbTriInFace; i++) {
- // Get the triangle
- Standard_Integer N1,N2,N3;
- Triangles(i).Get(N1,N2,N3);
-
- // change orientation of the triangles
- if ( orient != TopAbs_FORWARD )
- {
- Standard_Integer tmp = N1;
- N1 = N2;
- N2 = tmp;
- }
-
- gp_Pnt V1 = Nodes(N1);
- gp_Pnt V2 = Nodes(N2);
- gp_Pnt V3 = Nodes(N3);
-
- // transform the vertices to the place of the face
- if (!identity) {
- V1.Transform(myTransf);
- V2.Transform(myTransf);
- V3.Transform(myTransf);
- }
-
- // Calculate triangle normal
- gp_Vec v1(V1.X(),V1.Y(),V1.Z()),v2(V2.X(),V2.Y(),V2.Z()),v3(V3.X(),V3.Y(),V3.Z());
- gp_Vec Normal = (v2-v1)^(v3-v1);
-
- //Standard_Real Area = 0.5 * Normal.Magnitude();
-
- // add the triangle normal to the vertex normal for all points of this triangle
- (*vertexnormals)[N1-1] += gp_Vec(Normal.X(),Normal.Y(),Normal.Z());
- (*vertexnormals)[N2-1] += gp_Vec(Normal.X(),Normal.Y(),Normal.Z());
- (*vertexnormals)[N3-1] += gp_Vec(Normal.X(),Normal.Y(),Normal.Z());
-
- (*vertices)[N1-1].SetX((float)(V1.X()));
- (*vertices)[N1-1].SetY((float)(V1.Y()));
- (*vertices)[N1-1].SetZ((float)(V1.Z()));
- (*vertices)[N2-1].SetX((float)(V2.X()));
- (*vertices)[N2-1].SetY((float)(V2.Y()));
- (*vertices)[N2-1].SetZ((float)(V2.Z()));
- (*vertices)[N3-1].SetX((float)(V3.X()));
- (*vertices)[N3-1].SetY((float)(V3.Y()));
- (*vertices)[N3-1].SetZ((float)(V3.Z()));
-
- int j = i - 1;
- N1--;
- N2--;
- N3--;
- (*cons)[3*j] = N1;
- (*cons)[3*j+1] = N2;
- (*cons)[3*j+2] = N3;
- }
-
- // normalize all vertex normals
- for (i=0; i < nbNodesInFace; i++) {
-
- gp_Dir clNormal;
-
- try {
- Handle(Geom_Surface) Surface = BRep_Tool::Surface(aFace);
-
- gp_Pnt vertex((*vertices)[i].XYZ());
-// gp_Pnt vertex((*vertices)[i][0], (*vertices)[i][1], (*vertices)[i][2]);
- GeomAPI_ProjectPointOnSurf ProPntSrf(vertex, Surface);
- Standard_Real fU, fV;
- ProPntSrf.Parameters(1, fU, fV);
-
- GeomLProp_SLProps clPropOfFace(Surface, fU, fV, 2, gp::Resolution());
-
- clNormal = clPropOfFace.Normal();
- gp_Vec temp = clNormal;
- //Base::Console().Log("unterschied:%.2f",temp.dot((*vertexnormals)[i]));
- if ( temp * (*vertexnormals)[i] < 0 )
- temp = -temp;
- (*vertexnormals)[i] = temp;
-
- }
- catch (...) {
- }
-
- (*vertexnormals)[i].Normalize();
- }
-}
diff --git a/src/Mod/Raytracing/App/PovTools.h b/src/Mod/Raytracing/App/PovTools.h
index d499e003a08..09088c5755d 100644
--- a/src/Mod/Raytracing/App/PovTools.h
+++ b/src/Mod/Raytracing/App/PovTools.h
@@ -110,9 +110,6 @@ class AppRaytracingExport PovTools
const TopoDS_Shape& Shape,
float fMeshDeviation,
float fLength);
-
-
- static void transferToArray(const TopoDS_Face& aFace,gp_Vec** vertices,gp_Vec** vertexnormals, long** cons,int &nbNodesInFace,int &nbTriInFace );
};
From 08d46b5f882420c8d4066427fcc8dab5b1882097 Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Fri, 8 Oct 2021 15:28:22 +0200
Subject: [PATCH] Part: add methods to get the point normals of the
triangulation or surface
---
src/Mod/Part/App/Tools.cpp | 58 ++++++++++++++++++++++++++++++++++++++
src/Mod/Part/App/Tools.h | 17 +++++++++++
2 files changed, 75 insertions(+)
diff --git a/src/Mod/Part/App/Tools.cpp b/src/Mod/Part/App/Tools.cpp
index c0e59445089..41284befede 100644
--- a/src/Mod/Part/App/Tools.cpp
+++ b/src/Mod/Part/App/Tools.cpp
@@ -29,6 +29,7 @@
# include <Geom_BSplineSurface.hxx>
# include <Geom_Plane.hxx>
# include <GeomAPI_IntSS.hxx>
+# include <GeomAPI_ProjectPointOnSurf.hxx>
# include <Geom_Line.hxx>
# include <Geom_Point.hxx>
# include <GeomAdaptor_Curve.hxx>
@@ -356,3 +357,60 @@ bool Part::Tools::getPolygon3D(const TopoDS_Edge& edge, std::vector<gp_Pnt>& poi
return true;
}
+
+void Part::Tools::getPointNormals(const std::vector<gp_Pnt>& points, const std::vector<Poly_Triangle>& facets, std::vector<gp_Vec>& vertexnormals)
+{
+ vertexnormals.resize(points.size());
+
+ for (const auto& it : facets) {
+ // Get the triangle
+ Standard_Integer n1,n2,n3;
+ it.Get(n1,n2,n3);
+
+ // Calculate triangle normal
+ gp_Vec v1(points[n1].XYZ());
+ gp_Vec v2(points[n2].XYZ());
+ gp_Vec v3(points[n3].XYZ());
+ gp_Vec n = (v2 - v1) ^ (v3 - v1);
+
+ // add the triangle normal to the vertex normal for all points of this triangle
+ vertexnormals[n1] += n;
+ vertexnormals[n2] += n;
+ vertexnormals[n3] += n;
+ }
+
+ for (auto& it : vertexnormals)
+ it.Normalize();
+}
+
+void Part::Tools::getPointNormals(const std::vector<gp_Pnt>& points, const TopoDS_Face& face, std::vector<gp_Vec>& vertexnormals)
+{
+ if (points.size() != vertexnormals.size())
+ return;
+
+ Handle(Geom_Surface) hSurface = BRep_Tool::Surface(face);
+ if (hSurface.IsNull())
+ return;
+
+ // normalize all vertex normals
+ for (std::size_t i = 0; i < points.size(); i++) {
+ try {
+ GeomAPI_ProjectPointOnSurf ProPntSrf(points[i], hSurface);
+ Standard_Real u, v;
+ ProPntSrf.Parameters(1, u, v);
+
+ GeomLProp_SLProps propOfFace(hSurface, u, v, 2, gp::Resolution());
+
+ gp_Dir normal = propOfFace.Normal();
+ gp_Vec temp = normal;
+ if (temp * vertexnormals[i] < 0.0)
+ temp = -temp;
+ vertexnormals[i] = temp;
+
+ }
+ catch (...) {
+ }
+
+ vertexnormals[i].Normalize();
+ }
+}
diff --git a/src/Mod/Part/App/Tools.h b/src/Mod/Part/App/Tools.h
index 19ecf937fda..a487530a7dc 100644
--- a/src/Mod/Part/App/Tools.h
+++ b/src/Mod/Part/App/Tools.h
@@ -134,6 +134,23 @@ class PartExport Tools
* \return true if a polygon exists or false otherwise
*/
static bool getPolygon3D(const TopoDS_Edge& edge, std::vector<gp_Pnt>& points);
+ /*!
+ * \brief getPointNormals
+ * Calculate the point normals of the given triangulation.
+ * \param points
+ * \param facets
+ * \param normals
+ */
+ static void getPointNormals(const std::vector<gp_Pnt>& points, const std::vector<Poly_Triangle>& facets, std::vector<gp_Vec>& vertexnormals);
+ /*!
+ * \brief getPointNormals
+ * Computes the more accurate surface normals for the points. If the calculation for a point fails then the precomputed
+ * point normal of the triangulation is used.
+ * \param points
+ * \param face
+ * \param vertexnormals
+ */
+ static void getPointNormals(const std::vector<gp_Pnt>& points, const TopoDS_Face& face, std::vector<gp_Vec>& vertexnormals);
};
} //namespace Part
From 51e4366085e59a9b511f7160d66493e9b3dfc7d8 Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Mon, 11 Oct 2021 00:28:12 +0200
Subject: [PATCH] OCCT: port FreeCAD sources to version 7.6
---
src/Mod/Fem/App/FemConstraint.cpp | 12 ++++++++++--
src/Mod/Fem/App/FemConstraintFixed.cpp | 2 --
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/Mod/Fem/App/FemConstraint.cpp b/src/Mod/Fem/App/FemConstraint.cpp
index 18f72e87d20..8003fd6d79c 100644
--- a/src/Mod/Fem/App/FemConstraint.cpp
+++ b/src/Mod/Fem/App/FemConstraint.cpp
@@ -36,8 +36,6 @@
# include <BRepAdaptor_Curve.hxx>
# include <GCPnts_AbscissaPoint.hxx>
# include <Adaptor3d_IsoCurve.hxx>
-# include <Adaptor3d_HSurface.hxx>
-# include <BRepAdaptor_HSurface.hxx>
# include <BRepAdaptor_Surface.hxx>
# include <GProp_GProps.hxx>
# include <BRepGProp.hxx>
@@ -51,6 +49,11 @@
# include <Geom_Plane.hxx>
# include <Geom_Line.hxx>
# include <Precision.hxx>
+# include <Standard_Version.hxx>
+# if OCC_VERSION_HEX < 0x070600
+# include <Adaptor3d_HSurface.hxx>
+# include <BRepAdaptor_HSurface.hxx>
+# endif
#endif
#include "FemConstraint.h"
@@ -74,6 +77,11 @@ double round(double r) {
}
#endif
+#if OCC_VERSION_HEX >= 0x070600
+using Adaptor3d_HSurface = Adaptor3d_Surface;
+using BRepAdaptor_HSurface = BRepAdaptor_Surface;
+#endif
+
PROPERTY_SOURCE(Fem::Constraint, App::DocumentObject)
Constraint::Constraint()
diff --git a/src/Mod/Fem/App/FemConstraintFixed.cpp b/src/Mod/Fem/App/FemConstraintFixed.cpp
index 4d809454903..5b8874ec90b 100644
--- a/src/Mod/Fem/App/FemConstraintFixed.cpp
+++ b/src/Mod/Fem/App/FemConstraintFixed.cpp
@@ -32,8 +32,6 @@
#include <BRepAdaptor_Surface.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <Adaptor3d_IsoCurve.hxx>
-#include <Adaptor3d_HSurface.hxx>
-#include <BRepAdaptor_HSurface.hxx>
#include <GProp_GProps.hxx>
#include <BRepGProp.hxx>
#include <TopoDS_Vertex.hxx>
From c2c5ae1bf0c571270ecacf257a51e9b064fc609a Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Fri, 8 Oct 2021 19:34:48 +0200
Subject: [PATCH] Part: remove ViewProviderPartExt::getNormals
---
src/Mod/Part/Gui/ViewProviderExt.cpp | 91 +------------------
src/Mod/Part/Gui/ViewProviderExt.h | 2 -
src/Mod/PartDesign/Gui/ViewProviderAddSub.cpp | 5 +-
3 files changed, 5 insertions(+), 93 deletions(-)
diff --git a/src/Mod/Part/Gui/ViewProviderExt.cpp b/src/Mod/Part/Gui/ViewProviderExt.cpp
index ba197f18113..77cefbe3e08 100644
--- a/src/Mod/Part/Gui/ViewProviderExt.cpp
+++ b/src/Mod/Part/Gui/ViewProviderExt.cpp
@@ -125,6 +125,7 @@
#include <Mod/Part/App/PartFeature.h>
#include <Mod/Part/App/PrimitiveFeature.h>
+#include <Mod/Part/App/Tools.h>
FC_LOG_LEVEL_INIT("Part", true, true)
@@ -133,94 +134,6 @@ using namespace PartGui;
PROPERTY_SOURCE(PartGui::ViewProviderPartExt, Gui::ViewProviderGeometryObject)
-void ViewProviderPartExt::getNormals(const TopoDS_Face& theFace,
- const Handle(Poly_Triangulation)& aPolyTri,
- TColgp_Array1OfDir& theNormals)
-{
- const TColgp_Array1OfPnt& aNodes = aPolyTri->Nodes();
-
- if(aPolyTri->HasNormals())
- {
- // normals pre-computed in triangulation structure
- const TShort_Array1OfShortReal& aNormals = aPolyTri->Normals();
- const Standard_ShortReal* aNormArr = &(aNormals.Value(aNormals.Lower()));
-
- for(Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
- {
- const Standard_Integer anId = 3 * (aNodeIter - aNodes.Lower());
- const gp_Dir aNorm(aNormArr[anId + 0],
- aNormArr[anId + 1],
- aNormArr[anId + 2]);
- theNormals(aNodeIter) = aNorm;
- }
-
- if(theFace.Orientation() == TopAbs_REVERSED)
- {
- for(Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
- {
- theNormals.ChangeValue(aNodeIter).Reverse();
- }
- }
-
- return;
- }
-
- // take in face the surface location
- Poly_Connect thePolyConnect(aPolyTri);
- const TopoDS_Face aZeroFace = TopoDS::Face(theFace.Located(TopLoc_Location()));
- Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aZeroFace);
- const Standard_Real aTol = Precision::Confusion();
- Handle(TShort_HArray1OfShortReal) aNormals = new TShort_HArray1OfShortReal(1, aPolyTri->NbNodes() * 3);
- const Poly_Array1OfTriangle& aTriangles = aPolyTri->Triangles();
- const TColgp_Array1OfPnt2d* aNodesUV = aPolyTri->HasUVNodes() && !aSurf.IsNull()
- ? &aPolyTri->UVNodes()
- : NULL;
- Standard_Integer aTri[3];
-
- for(Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
- {
- // try to retrieve normal from real surface first, when UV coordinates are available
- if(aNodesUV == NULL
- || GeomLib::NormEstim(aSurf, aNodesUV->Value(aNodeIter), aTol, theNormals(aNodeIter)) > 1)
- {
- // compute flat normals
- gp_XYZ eqPlan(0.0, 0.0, 0.0);
-
- for(thePolyConnect.Initialize(aNodeIter); thePolyConnect.More(); thePolyConnect.Next())
- {
- aTriangles(thePolyConnect.Value()).Get(aTri[0], aTri[1], aTri[2]);
- const gp_XYZ v1(aNodes(aTri[1]).Coord() - aNodes(aTri[0]).Coord());
- const gp_XYZ v2(aNodes(aTri[2]).Coord() - aNodes(aTri[1]).Coord());
- const gp_XYZ vv = v1 ^ v2;
- const Standard_Real aMod = vv.Modulus();
-
- if(aMod >= aTol)
- {
- eqPlan += vv / aMod;
- }
- }
-
- const Standard_Real aModMax = eqPlan.Modulus();
- theNormals(aNodeIter) = (aModMax > aTol) ? gp_Dir(eqPlan) : gp::DZ();
- }
-
- const Standard_Integer anId = (aNodeIter - aNodes.Lower()) * 3;
- aNormals->SetValue(anId + 1, (Standard_ShortReal)theNormals(aNodeIter).X());
- aNormals->SetValue(anId + 2, (Standard_ShortReal)theNormals(aNodeIter).Y());
- aNormals->SetValue(anId + 3, (Standard_ShortReal)theNormals(aNodeIter).Z());
- }
-
- aPolyTri->SetNormals(aNormals);
-
- if(theFace.Orientation() == TopAbs_REVERSED)
- {
- for(Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
- {
- theNormals.ChangeValue(aNodeIter).Reverse();
- }
- }
-}
-
//**************************************************************************
// Construction/Destruction
@@ -1174,7 +1087,7 @@ void ViewProviderPartExt::updateVisual()
const TColgp_Array1OfPnt& Nodes = mesh->Nodes();
TColgp_Array1OfDir Normals (Nodes.Lower(), Nodes.Upper());
if (NormalsFromUV)
- getNormals(actFace, mesh, Normals);
+ Part::Tools::getPointNormals(actFace, mesh, Normals);
for (int g=1;g<=nbTriInFace;g++) {
// Get the triangle
diff --git a/src/Mod/Part/Gui/ViewProviderExt.h b/src/Mod/Part/Gui/ViewProviderExt.h
index d890e9a716e..2cb55c1873c 100644
--- a/src/Mod/Part/Gui/ViewProviderExt.h
+++ b/src/Mod/Part/Gui/ViewProviderExt.h
@@ -158,8 +158,6 @@ class PartGuiExport ViewProviderPartExt : public Gui::ViewProviderGeometryObject
virtual void onChanged(const App::Property* prop) override;
bool loadParameter();
void updateVisual();
- void getNormals(const TopoDS_Face& theFace, const Handle(Poly_Triangulation)& aPolyTri,
- TColgp_Array1OfDir& theNormals);
// nodes for the data representation
SoMaterialBinding * pcFaceBind;
diff --git a/src/Mod/PartDesign/Gui/ViewProviderAddSub.cpp b/src/Mod/PartDesign/Gui/ViewProviderAddSub.cpp
index 85bcf6e551d..642eb9dc76a 100644
--- a/src/Mod/PartDesign/Gui/ViewProviderAddSub.cpp
+++ b/src/Mod/PartDesign/Gui/ViewProviderAddSub.cpp
@@ -40,7 +40,8 @@
#endif
#include "ViewProviderAddSub.h"
-#include "Mod/Part/Gui/SoBrepFaceSet.h"
+#include <Mod/Part/Gui/SoBrepFaceSet.h>
+#include <Mod/Part/App/Tools.h>
#include <Mod/PartDesign/App/FeatureAddSub.h>
#include <Gui/TaskView/TaskDialog.h>
#include <Gui/Control.h>
@@ -196,7 +197,7 @@ void ViewProviderAddSub::updateAddSubShapeIndicator() {
const Poly_Array1OfTriangle& Triangles = mesh->Triangles();
const TColgp_Array1OfPnt& Nodes = mesh->Nodes();
TColgp_Array1OfDir Normals (Nodes.Lower(), Nodes.Upper());
- getNormals(actFace, mesh, Normals);
+ Part::Tools::getPointNormals(actFace, mesh, Normals);
for (int g=1;g<=nbTriInFace;g++) {
// Get the triangle
From 302568d177ddde171c28eaca89e8b4a49466974f Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Fri, 8 Oct 2021 16:55:09 +0200
Subject: [PATCH] Part: copy ViewProviderPartExt::getNormals to Tools class
---
src/Mod/Part/App/PreCompiled.h | 1 +
src/Mod/Part/App/Tools.cpp | 87 ++++++++++++++++++++++++++++++++++
src/Mod/Part/App/Tools.h | 3 ++
3 files changed, 91 insertions(+)
diff --git a/src/Mod/Part/App/PreCompiled.h b/src/Mod/Part/App/PreCompiled.h
index bb9b1cb04fb..636b5ea3cb8 100644
--- a/src/Mod/Part/App/PreCompiled.h
+++ b/src/Mod/Part/App/PreCompiled.h
@@ -94,6 +94,7 @@
#include "OpenCascadeAll.h"
#include <math_Gauss.hxx>
#include <math_Matrix.hxx>
+#include <Poly_Connect.hxx>
#elif defined(FC_OS_WIN32)
#define WIN32_LEAN_AND_MEAN
diff --git a/src/Mod/Part/App/Tools.cpp b/src/Mod/Part/App/Tools.cpp
index 41284befede..74664dfa50a 100644
--- a/src/Mod/Part/App/Tools.cpp
+++ b/src/Mod/Part/App/Tools.cpp
@@ -33,11 +33,13 @@
# include <Geom_Line.hxx>
# include <Geom_Point.hxx>
# include <GeomAdaptor_Curve.hxx>
+# include <GeomLib.hxx>
# include <GeomPlate_BuildPlateSurface.hxx>
# include <GeomPlate_CurveConstraint.hxx>
# include <GeomPlate_MakeApprox.hxx>
# include <GeomPlate_PlateG0Criterion.hxx>
# include <GeomPlate_PointConstraint.hxx>
+# include <Poly_Connect.hxx>
# include <Poly_Triangulation.hxx>
# include <Precision.hxx>
# include <Standard_Mutex.hxx>
@@ -47,6 +49,7 @@
# include <TColStd_ListIteratorOfListOfTransient.hxx>
# include <TColgp_SequenceOfXY.hxx>
# include <TColgp_SequenceOfXYZ.hxx>
+# include <TopoDS.hxx>
# if OCC_VERSION_HEX < 0x070600
# include <Adaptor3d_HCurveOnSurface.hxx>
# include <GeomAdaptor_HCurve.hxx>
@@ -414,3 +417,87 @@ void Part::Tools::getPointNormals(const std::vector<gp_Pnt>& points, const TopoD
vertexnormals[i].Normalize();
}
}
+
+void Part::Tools::getPointNormals(const TopoDS_Face& theFace, Handle(Poly_Triangulation) aPolyTri, TColgp_Array1OfDir& theNormals)
+{
+ const TColgp_Array1OfPnt& aNodes = aPolyTri->Nodes();
+
+ if(aPolyTri->HasNormals())
+ {
+ // normals pre-computed in triangulation structure
+ const TShort_Array1OfShortReal& aNormals = aPolyTri->Normals();
+ const Standard_ShortReal* aNormArr = &(aNormals.Value(aNormals.Lower()));
+
+ for(Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
+ {
+ const Standard_Integer anId = 3 * (aNodeIter - aNodes.Lower());
+ const gp_Dir aNorm(aNormArr[anId + 0],
+ aNormArr[anId + 1],
+ aNormArr[anId + 2]);
+ theNormals(aNodeIter) = aNorm;
+ }
+
+ if(theFace.Orientation() == TopAbs_REVERSED)
+ {
+ for(Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
+ {
+ theNormals.ChangeValue(aNodeIter).Reverse();
+ }
+ }
+ }
+ else {
+ // take in face the surface location
+ Poly_Connect thePolyConnect(aPolyTri);
+ const TopoDS_Face aZeroFace = TopoDS::Face(theFace.Located(TopLoc_Location()));
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aZeroFace);
+ const Standard_Real aTol = Precision::Confusion();
+ Handle(TShort_HArray1OfShortReal) aNormals = new TShort_HArray1OfShortReal(1, aPolyTri->NbNodes() * 3);
+ const Poly_Array1OfTriangle& aTriangles = aPolyTri->Triangles();
+ const TColgp_Array1OfPnt2d* aNodesUV = aPolyTri->HasUVNodes() && !aSurf.IsNull()
+ ? &aPolyTri->UVNodes()
+ : nullptr;
+ Standard_Integer aTri[3];
+
+ for(Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
+ {
+ // try to retrieve normal from real surface first, when UV coordinates are available
+ if (!aNodesUV || GeomLib::NormEstim(aSurf, aNodesUV->Value(aNodeIter), aTol, theNormals(aNodeIter)) > 1)
+ {
+ // compute flat normals
+ gp_XYZ eqPlan(0.0, 0.0, 0.0);
+
+ for(thePolyConnect.Initialize(aNodeIter); thePolyConnect.More(); thePolyConnect.Next())
+ {
+ aTriangles(thePolyConnect.Value()).Get(aTri[0], aTri[1], aTri[2]);
+ const gp_XYZ v1(aNodes(aTri[1]).Coord() - aNodes(aTri[0]).Coord());
+ const gp_XYZ v2(aNodes(aTri[2]).Coord() - aNodes(aTri[1]).Coord());
+ const gp_XYZ vv = v1 ^ v2;
+ const Standard_Real aMod = vv.Modulus();
+
+ if(aMod >= aTol)
+ {
+ eqPlan += vv / aMod;
+ }
+ }
+
+ const Standard_Real aModMax = eqPlan.Modulus();
+ theNormals(aNodeIter) = (aModMax > aTol) ? gp_Dir(eqPlan) : gp::DZ();
+ }
+
+ const Standard_Integer anId = (aNodeIter - aNodes.Lower()) * 3;
+ aNormals->SetValue(anId + 1, (Standard_ShortReal)theNormals(aNodeIter).X());
+ aNormals->SetValue(anId + 2, (Standard_ShortReal)theNormals(aNodeIter).Y());
+ aNormals->SetValue(anId + 3, (Standard_ShortReal)theNormals(aNodeIter).Z());
+ }
+
+ aPolyTri->SetNormals(aNormals);
+
+ if(theFace.Orientation() == TopAbs_REVERSED)
+ {
+ for(Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
+ {
+ theNormals.ChangeValue(aNodeIter).Reverse();
+ }
+ }
+ }
+}
diff --git a/src/Mod/Part/App/Tools.h b/src/Mod/Part/App/Tools.h
index a487530a7dc..43a01123b71 100644
--- a/src/Mod/Part/App/Tools.h
+++ b/src/Mod/Part/App/Tools.h
@@ -31,7 +31,9 @@
#include <gp_XYZ.hxx>
#include <Geom_Surface.hxx>
#include <Poly_Triangle.hxx>
+#include <Poly_Triangulation.hxx>
#include <TColStd_ListOfTransient.hxx>
+#include <TColgp_Array1OfDir.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <vector>
@@ -151,6 +153,7 @@ class PartExport Tools
* \param vertexnormals
*/
static void getPointNormals(const std::vector<gp_Pnt>& points, const TopoDS_Face& face, std::vector<gp_Vec>& vertexnormals);
+ static void getPointNormals(const TopoDS_Face& face, Handle(Poly_Triangulation) aPoly, TColgp_Array1OfDir& normals);
};
} //namespace Part
From 66d3dd897f63c2e4f8ffd6eced730c6a3372ad51 Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Sat, 9 Oct 2021 11:37:18 +0200
Subject: [PATCH] Part: add convenience function to convert TColgp_Array1OfDir
to std::vector
---
src/Mod/Part/App/Tools.cpp | 88 ++++++++++++++++++++++++++++++++++++++
src/Mod/Part/App/Tools.h | 23 ++++++++++
2 files changed, 111 insertions(+)
diff --git a/src/Mod/Part/App/Tools.cpp b/src/Mod/Part/App/Tools.cpp
index 74664dfa50a..0a85e0c6df6 100644
--- a/src/Mod/Part/App/Tools.cpp
+++ b/src/Mod/Part/App/Tools.cpp
@@ -420,6 +420,7 @@ void Part::Tools::getPointNormals(const std::vector<gp_Pnt>& points, const TopoD
void Part::Tools::getPointNormals(const TopoDS_Face& theFace, Handle(Poly_Triangulation) aPolyTri, TColgp_Array1OfDir& theNormals)
{
+#if OCC_VERSION_HEX < 0x070600
const TColgp_Array1OfPnt& aNodes = aPolyTri->Nodes();
if(aPolyTri->HasNormals())
@@ -500,4 +501,91 @@ void Part::Tools::getPointNormals(const TopoDS_Face& theFace, Handle(Poly_Triang
}
}
}
+#else
+ Standard_Integer numNodes = aPolyTri->NbNodes();
+
+ if(aPolyTri->HasNormals())
+ {
+ for(Standard_Integer aNodeIter = 1; aNodeIter <= numNodes; ++aNodeIter)
+ {
+ theNormals(aNodeIter) = aPolyTri->Normal(aNodeIter);
+ }
+
+ if(theFace.Orientation() == TopAbs_REVERSED)
+ {
+ for(Standard_Integer aNodeIter = 1; aNodeIter <= numNodes; ++aNodeIter)
+ {
+ theNormals.ChangeValue(aNodeIter).Reverse();
+ }
+ }
+ }
+ else {
+ // take in face the surface location
+ Poly_Connect thePolyConnect(aPolyTri);
+ const TopoDS_Face aZeroFace = TopoDS::Face(theFace.Located(TopLoc_Location()));
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aZeroFace);
+ const Standard_Real aTol = Precision::Confusion();
+ Standard_Boolean hasNodesUV = aPolyTri->HasUVNodes() && !aSurf.IsNull();
+ Standard_Integer aTri[3];
+
+ for(Standard_Integer aNodeIter = 1; aNodeIter <= numNodes; ++aNodeIter)
+ {
+ // try to retrieve normal from real surface first, when UV coordinates are available
+ if (!hasNodesUV || GeomLib::NormEstim(aSurf, aPolyTri->UVNode(aNodeIter), aTol, theNormals(aNodeIter)) > 1)
+ {
+ // compute flat normals
+ gp_XYZ eqPlan(0.0, 0.0, 0.0);
+
+ for(thePolyConnect.Initialize(aNodeIter); thePolyConnect.More(); thePolyConnect.Next())
+ {
+ aPolyTri->Triangle(thePolyConnect.Value()).Get(aTri[0], aTri[1], aTri[2]);
+ const gp_XYZ v1(aPolyTri->Node(aTri[1]).Coord() - aPolyTri->Node(aTri[0]).Coord());
+ const gp_XYZ v2(aPolyTri->Node(aTri[2]).Coord() - aPolyTri->Node(aTri[1]).Coord());
+ const gp_XYZ vv = v1 ^ v2;
+ const Standard_Real aMod = vv.Modulus();
+
+ if(aMod >= aTol)
+ {
+ eqPlan += vv / aMod;
+ }
+ }
+
+ const Standard_Real aModMax = eqPlan.Modulus();
+ theNormals(aNodeIter) = (aModMax > aTol) ? gp_Dir(eqPlan) : gp::DZ();
+ }
+
+ aPolyTri->SetNormal(aNodeIter, theNormals(aNodeIter));
+ }
+
+ if(theFace.Orientation() == TopAbs_REVERSED)
+ {
+ for(Standard_Integer aNodeIter = 1; aNodeIter <= numNodes; ++aNodeIter)
+ {
+ theNormals.ChangeValue(aNodeIter).Reverse();
+ }
+ }
+ }
+#endif
+}
+
+void Part::Tools::getPointNormals(const TopoDS_Face& face, Handle(Poly_Triangulation) aPoly, std::vector<gp_Vec>& normals)
+{
+ TColgp_Array1OfDir dirs (1, aPoly->NbNodes());
+ getPointNormals(face, aPoly, dirs);
+ normals.reserve(aPoly->NbNodes());
+
+ for (int i = dirs.Lower(); i <= dirs.Upper(); ++i) {
+ normals.emplace_back(dirs(i).XYZ());
+ }
+}
+
+void Part::Tools::applyTransformationOnNormals(const TopLoc_Location& loc, std::vector<gp_Vec>& normals)
+{
+ if (!loc.IsIdentity()) {
+ gp_Trsf myTransf = loc.Transformation();
+
+ for (auto& it : normals) {
+ it.Transform(myTransf);
+ }
+ }
}
diff --git a/src/Mod/Part/App/Tools.h b/src/Mod/Part/App/Tools.h
index 43a01123b71..425032a12d9 100644
--- a/src/Mod/Part/App/Tools.h
+++ b/src/Mod/Part/App/Tools.h
@@ -34,6 +34,7 @@
#include <Poly_Triangulation.hxx>
#include <TColStd_ListOfTransient.hxx>
#include <TColgp_Array1OfDir.hxx>
+#include <TopLoc_Location.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <vector>
@@ -153,7 +154,29 @@ class PartExport Tools
* \param vertexnormals
*/
static void getPointNormals(const std::vector<gp_Pnt>& points, const TopoDS_Face& face, std::vector<gp_Vec>& vertexnormals);
+ /*!
+ * \brief getPointNormals
+ * Computes the exact surface normals for the points by using the UV coordinates of the mesh vertexes.
+ * \param face
+ * \param aPoly
+ * \param vertexnormals
+ */
static void getPointNormals(const TopoDS_Face& face, Handle(Poly_Triangulation) aPoly, TColgp_Array1OfDir& normals);
+ /*!
+ * \brief getPointNormals
+ * Computes the exact surface normals for the points by using the UV coordinates of the mesh vertexes.
+ * \param face
+ * \param aPoly
+ * \param vertexnormals
+ */
+ static void getPointNormals(const TopoDS_Face& face, Handle(Poly_Triangulation) aPoly, std::vector<gp_Vec>& normals);
+ /*!
+ * \brief applyTransformationOnNormals
+ * Apply the transformation to the vectors
+ * \param loc
+ * \param normals
+ */
+ static void applyTransformationOnNormals(const TopLoc_Location& loc, std::vector<gp_Vec>& normals);
};
} //namespace Part
From 03be15cc6b460ab62548142287eb9f677f463a44 Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Sat, 9 Oct 2021 14:34:04 +0200
Subject: [PATCH] Part: fix bug in Part::Tools::getPointNormals for OCCT 7.6
---
src/Mod/Part/App/Tools.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Mod/Part/App/Tools.cpp b/src/Mod/Part/App/Tools.cpp
index 0a85e0c6df6..d95e49eaf4f 100644
--- a/src/Mod/Part/App/Tools.cpp
+++ b/src/Mod/Part/App/Tools.cpp
@@ -528,6 +528,7 @@ void Part::Tools::getPointNormals(const TopoDS_Face& theFace, Handle(Poly_Triang
Standard_Boolean hasNodesUV = aPolyTri->HasUVNodes() && !aSurf.IsNull();
Standard_Integer aTri[3];
+ aPolyTri->AddNormals();
for(Standard_Integer aNodeIter = 1; aNodeIter <= numNodes; ++aNodeIter)
{
// try to retrieve normal from real surface first, when UV coordinates are available
From f628050732cc5d1d49fc18282ed508ca3061bb10 Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Sat, 9 Oct 2021 11:38:25 +0200
Subject: [PATCH] PD: simplify code to display add/sub shape
---
src/Mod/PartDesign/Gui/ViewProviderAddSub.cpp | 111 ++++++------------
1 file changed, 39 insertions(+), 72 deletions(-)
diff --git a/src/Mod/PartDesign/Gui/ViewProviderAddSub.cpp b/src/Mod/PartDesign/Gui/ViewProviderAddSub.cpp
index 642eb9dc76a..2e2d2a55e54 100644
--- a/src/Mod/PartDesign/Gui/ViewProviderAddSub.cpp
+++ b/src/Mod/PartDesign/Gui/ViewProviderAddSub.cpp
@@ -116,9 +116,6 @@ void ViewProviderAddSub::updateAddSubShapeIndicator() {
return;
}
- int numTriangles=0,numNodes=0,numNorms=0,numFaces=0;
- std::set<int> faceEdges;
-
try {
// calculating the deflection value
Bnd_Box bounds;
@@ -126,16 +123,14 @@ void ViewProviderAddSub::updateAddSubShapeIndicator() {
bounds.SetGap(0.0);
Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax);
- Standard_Real deflection = ((xMax-xMin)+(yMax-yMin)+(zMax-zMin))/300.0 *
- Deviation.getValue();
+ Standard_Real deflection = ((xMax-xMin)+(yMax-yMin)+(zMax-zMin))/300.0 * Deviation.getValue();
// create or use the mesh on the data structure
#if OCC_VERSION_HEX >= 0x060600
Standard_Real AngDeflectionRads = AngularDeflection.getValue() / 180.0 * M_PI;
- BRepMesh_IncrementalMesh(cShape,deflection,Standard_False,
- AngDeflectionRads,Standard_True);
+ BRepMesh_IncrementalMesh(cShape, deflection, Standard_False, AngDeflectionRads, Standard_True);
#else
- BRepMesh_IncrementalMesh(cShape,deflection);
+ BRepMesh_IncrementalMesh(cShape, deflection);
#endif
// We must reset the location here because the transformation data
// are set in the placement property
@@ -143,6 +138,7 @@ void ViewProviderAddSub::updateAddSubShapeIndicator() {
cShape.Location(aLoc);
// count triangles and nodes in the mesh
+ int numTriangles=0,numNodes=0,numNorms=0,numFaces=0;
TopExp_Explorer Ex;
for (Ex.Init(cShape,TopAbs_FACE);Ex.More();Ex.Next()) {
Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(TopoDS::Face(Ex.Current()), aLoc);
@@ -160,11 +156,12 @@ void ViewProviderAddSub::updateAddSubShapeIndicator() {
previewNorm ->vector .setNum(numNorms);
previewFaceSet ->coordIndex .setNum(numTriangles*4);
previewFaceSet ->partIndex .setNum(numFaces);
+
// get the raw memory for fast fill up
- SbVec3f* verts = previewCoords ->point .startEditing();
- SbVec3f* previewNorms = previewNorm ->vector .startEditing();
- int32_t* index = previewFaceSet ->coordIndex .startEditing();
- int32_t* parts = previewFaceSet ->partIndex .startEditing();
+ SbVec3f* verts = previewCoords ->point .startEditing();
+ SbVec3f* previewNorms = previewNorm ->vector .startEditing();
+ int32_t* index = previewFaceSet ->coordIndex .startEditing();
+ int32_t* parts = previewFaceSet ->partIndex .startEditing();
// preset the previewNormal vector with null vector
for (int i=0;i < numNorms;i++)
@@ -172,76 +169,46 @@ void ViewProviderAddSub::updateAddSubShapeIndicator() {
int ii = 0,faceNodeOffset=0,faceTriaOffset=0;
for (Ex.Init(cShape, TopAbs_FACE); Ex.More(); Ex.Next(),ii++) {
- TopLoc_Location aLoc;
const TopoDS_Face &actFace = TopoDS::Face(Ex.Current());
- // get the mesh of the shape
- Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(actFace,aLoc);
- if (mesh.IsNull()) continue;
-
- // getting the transformation of the shape/face
- gp_Trsf myTransf;
- Standard_Boolean identity = true;
- if (!aLoc.IsIdentity()) {
- identity = false;
- myTransf = aLoc.Transformation();
- }
+
+ TopLoc_Location loc;
+ Handle(Poly_Triangulation) mesh = BRep_Tool::Triangulation(actFace, loc);
+ if (mesh.IsNull())
+ continue;
+
+ // get triangulation
+ std::vector<gp_Pnt> points;
+ std::vector<Poly_Triangle> facets;
+ Part::Tools::getTriangulation(actFace, points, facets);
+
+ // get normal per vertex
+ std::vector<gp_Vec> vertexnormals;
+ Part::Tools::getPointNormals(actFace, mesh, vertexnormals);
+ Part::Tools::applyTransformationOnNormals(loc, vertexnormals);
// getting size of node and triangle array of this face
- int nbNodesInFace = mesh->NbNodes();
- int nbTriInFace = mesh->NbTriangles();
- // check orientation
- TopAbs_Orientation orient = actFace.Orientation();
+ std::size_t nbNodesInFace = points.size();
+ std::size_t nbTriInFace = facets.size();
+ for (std::size_t i = 0; i < points.size(); i++) {
+ verts[faceNodeOffset+i] = SbVec3f(points[i].X(), points[i].Y(), points[i].Z());
+ }
- // cycling through the poly mesh
- const Poly_Array1OfTriangle& Triangles = mesh->Triangles();
- const TColgp_Array1OfPnt& Nodes = mesh->Nodes();
- TColgp_Array1OfDir Normals (Nodes.Lower(), Nodes.Upper());
- Part::Tools::getPointNormals(actFace, mesh, Normals);
+ for (std::size_t i = 0; i < vertexnormals.size(); i++) {
+ previewNorms[faceNodeOffset+i] = SbVec3f(vertexnormals[i].X(), vertexnormals[i].Y(), vertexnormals[i].Z());
+ }
- for (int g=1;g<=nbTriInFace;g++) {
+ // cycling through the poly mesh
+ for (std::size_t g=0; g < nbTriInFace; g++) {
// Get the triangle
Standard_Integer N1,N2,N3;
- Triangles(g).Get(N1,N2,N3);
-
- // change orientation of the triangle if the face is reversed
- if ( orient != TopAbs_FORWARD ) {
- Standard_Integer tmp = N1;
- N1 = N2;
- N2 = tmp;
- }
-
- // get the 3 points of this triangle
- gp_Pnt V1(Nodes(N1)), V2(Nodes(N2)), V3(Nodes(N3));
-
- // get the 3 previewNormals of this triangle
- gp_Dir NV1(Normals(N1)), NV2(Normals(N2)), NV3(Normals(N3));
-
- // transform the vertices and previewNormals to the place of the face
- if(!identity) {
- V1.Transform(myTransf);
- V2.Transform(myTransf);
- V3.Transform(myTransf);
- NV1.Transform(myTransf);
- NV2.Transform(myTransf);
- NV3.Transform(myTransf);
- }
-
- // add the previewNormals for all points of this triangle
- previewNorms[faceNodeOffset+N1-1] += SbVec3f(NV1.X(),NV1.Y(),NV1.Z());
- previewNorms[faceNodeOffset+N2-1] += SbVec3f(NV2.X(),NV2.Y(),NV2.Z());
- previewNorms[faceNodeOffset+N3-1] += SbVec3f(NV3.X(),NV3.Y(),NV3.Z());
-
- // set the vertices
- verts[faceNodeOffset+N1-1].setValue((float)(V1.X()),(float)(V1.Y()),(float)(V1.Z()));
- verts[faceNodeOffset+N2-1].setValue((float)(V2.X()),(float)(V2.Y()),(float)(V2.Z()));
- verts[faceNodeOffset+N3-1].setValue((float)(V3.X()),(float)(V3.Y()),(float)(V3.Z()));
+ facets[g].Get(N1,N2,N3);
// set the index vector with the 3 point indexes and the end delimiter
- index[faceTriaOffset*4+4*(g-1)] = faceNodeOffset+N1-1;
- index[faceTriaOffset*4+4*(g-1)+1] = faceNodeOffset+N2-1;
- index[faceTriaOffset*4+4*(g-1)+2] = faceNodeOffset+N3-1;
- index[faceTriaOffset*4+4*(g-1)+3] = SO_END_FACE_INDEX;
+ index[faceTriaOffset*4+4*g] = faceNodeOffset+N1;
+ index[faceTriaOffset*4+4*g+1] = faceNodeOffset+N2;
+ index[faceTriaOffset*4+4*g+2] = faceNodeOffset+N3;
+ index[faceTriaOffset*4+4*g+3] = SO_END_FACE_INDEX;
}
parts[ii] = nbTriInFace; // new part
From 16ff933b09176d83fb0785e74f36038311f0eaeb Mon Sep 17 00:00:00 2001
From: David Osterberg <davost@gmail.com>
Date: Sat, 27 Feb 2021 09:27:23 +0100
Subject: [PATCH] PartDesign: Transformded. Align the "property category" of
Refine with other PD commands
---
src/Mod/PartDesign/App/FeatureTransformed.cpp | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/Mod/PartDesign/App/FeatureTransformed.cpp b/src/Mod/PartDesign/App/FeatureTransformed.cpp
index 1818338dbcf..d24a0199f20 100644
--- a/src/Mod/PartDesign/App/FeatureTransformed.cpp
+++ b/src/Mod/PartDesign/App/FeatureTransformed.cpp
@@ -65,7 +65,7 @@ Transformed::Transformed()
Originals.setSize(0);
Placement.setStatus(App::Property::ReadOnly, true);
- ADD_PROPERTY_TYPE(Refine,(0),"SketchBased",(App::PropertyType)(App::Prop_None),"Refine shape (clean up redundant edges) after adding/subtracting");
+ ADD_PROPERTY_TYPE(Refine,(0),"Part Design",(App::PropertyType)(App::Prop_None),"Refine shape (clean up redundant edges) after adding/subtracting");
//init Refine property
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
@@ -89,7 +89,7 @@ Part::Feature* Transformed::getBaseObject(bool silent) const {
const char* err = nullptr;
const std::vector<App::DocumentObject*> & originals = Originals.getValues();
- // NOTE: may be here supposed to be last origin but in order to keep the old behaviour keep here first
+ // NOTE: may be here supposed to be last origin but in order to keep the old behaviour keep here first
App::DocumentObject* firstOriginal = originals.empty() ? NULL : originals.front();
if (firstOriginal) {
if(firstOriginal->isDerivedFrom(Part::Feature::getClassTypeId())) {
@@ -272,7 +272,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
fuseShape = fuseShape.makETransform(trsf);
if (!cutShape.isNull())
cutShape = cutShape.makETransform(trsf);
- }
+ }
else {
return new App::DocumentObjectExecReturn("Only additive and subtractive features can be transformed");
}
@@ -323,17 +323,17 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
//
// Therefore, if the transformation succeeded, then we fuse it with the support now, before checking the intersection
// of the next transformation.
-
+
/*v_transformations.push_back(t);
v_transformedShapes.push_back(mkTrf.Shape());*/
-
+
// Note: Transformations that do not intersect the support are ignored in the overlap tests
-
+
//insert scheme here.
/*TopoDS_Compound compoundTool;
std::vector<TopoDS_Shape> individualTools;
divideTools(v_transformedShapes, individualTools, compoundTool);*/
-
+
// Fuse/Cut the compounded transformed shapes with the support
//TopoDS_Shape result;
@@ -361,7 +361,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
shape = copy.Shape();
if (shape.IsNull())
return new App::DocumentObjectExecReturn("Transformed: Linked shape object is empty");
-
+
BRepBuilderAPI_Transform mkTrf(shape, *t, false); // No need to copy, now
if (!mkTrf.IsDone())
return new App::DocumentObjectExecReturn("Transformation failed", (*o));
@@ -378,7 +378,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
} catch (Standard_Failure& e) {
// Note: Ignoring this failure is probably pointless because if the intersection check fails, the later
// fuse operation of the transformation result will also fail
-
+
std::string msg("Transformation: Intersection check failed");
if (e.GetMessageString() != NULL)
msg += std::string(": '") + e.GetMessageString() + "'";
From 03da9d3501c6b596ad1828b99cb8d923cea56485 Mon Sep 17 00:00:00 2001
From: David Osterberg <davost@gmail.com>
Date: Sun, 21 Feb 2021 15:33:35 +0100
Subject: [PATCH] PartDesign: Performance improvements in Transformed (pattern)
- Use fuzzy fuse/cut method with tolerance Precision::Confusion()
- Use parallel computation feature
- Allow that individual patterned item fail to intersect the baseobject.
Issue warning instead of error. This was done for performance reasons
but it can also be considered a feature.
- Simplify the code a bit
- Distinguish between overlapping mode and non-overlapping mode. In non-overlapping mode
the tool shapes are compounded instead of fused. For huge benefit in performance.
---
src/Mod/PartDesign/App/FeatureTransformed.cpp | 191 ++++++++----------
1 file changed, 79 insertions(+), 112 deletions(-)
diff --git a/src/Mod/PartDesign/App/FeatureTransformed.cpp b/src/Mod/PartDesign/App/FeatureTransformed.cpp
index d24a0199f20..9e638f32d7f 100644
--- a/src/Mod/PartDesign/App/FeatureTransformed.cpp
+++ b/src/Mod/PartDesign/App/FeatureTransformed.cpp
@@ -36,6 +36,9 @@
# include <Bnd_Box.hxx>
#endif
+#ifndef FC_DEBUG
+#include <ctime>
+#endif
#include "FeatureTransformed.h"
#include "FeatureMultiTransform.h"
@@ -198,7 +201,11 @@ short Transformed::mustExecute() const
App::DocumentObjectExecReturn *Transformed::execute(void)
{
- rejected.clear();
+
+#ifndef FC_DEBUG
+ std::clock_t start0;
+ start0 = std::clock();
+#endif
std::vector<App::DocumentObject*> originals = Originals.getValues();
if (originals.empty()) // typically InsideMultiTransform
@@ -246,10 +253,6 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
supportShape.setTransform(Base::Matrix4D());
TopoDS_Shape support = supportShape.getShape();
- typedef std::set<std::vector<gp_Trsf>::const_iterator> trsf_it;
- typedef std::map<App::DocumentObject*, trsf_it> rej_it_map;
- rej_it_map nointersect_trsfms;
-
// NOTE: It would be possible to build a compound from all original addShapes/subShapes and then
// transform the compounds as a whole. But we choose to apply the transformations to each
// Original separately. This way it is easier to discover what feature causes a fuse/cut
@@ -276,132 +279,93 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
else {
return new App::DocumentObjectExecReturn("Only additive and subtractive features can be transformed");
}
+ TopoDS_Shape origShape = fuseShape.isNull()?cutShape.getShape():fuseShape.getShape();
+
+ TopoDS_Shape current = support;
- // Transform the add/subshape and collect the resulting shapes for overlap testing
- /*typedef std::vector<std::vector<gp_Trsf>::const_iterator> trsf_it_vec;
- trsf_it_vec v_transformations;
- std::vector<TopoDS_Shape> v_transformedShapes;*/
+ BRep_Builder builder;
+ TopoDS_Compound compShape;
+ builder.MakeCompound(compShape);
+ std::vector<TopoDS_Shape> shapes;
+ bool overlapping = false;
std::vector<gp_Trsf>::const_iterator t = transformations.begin();
++t; // Skip first transformation, which is always the identity transformation
for (; t != transformations.end(); ++t) {
// Make an explicit copy of the shape because the "true" parameter to BRepBuilderAPI_Transform
// seems to be pretty broken
- BRepBuilderAPI_Copy copy(fuseShape.isNull()?cutShape.getShape():fuseShape.getShape());
+ BRepBuilderAPI_Copy copy(origShape);
+
shape = copy.Shape();
- if (shape.IsNull())
- return new App::DocumentObjectExecReturn("Transformed: Linked shape object is empty");
-
- BRepBuilderAPI_Transform mkTrf(shape, *t, false); // No need to copy, now
- if (!mkTrf.IsDone())
- return new App::DocumentObjectExecReturn("Transformation failed", (*o));
-
- shape = mkTrf.Shape();
- try {
- // Intersection checking for additive shape is redundant.
- // Because according to CheckIntersection() source code, it is
- // implemented using fusion and counting of the resulting
- // solid, which will be done in the following modeling step
- // anyway.
- //
- // There is little reason for doing intersection checking on
- // subtractive shape either, because it does not produce
- // multiple solids.
- //
- // if (!Part::checkIntersection(support, mkTrf.Shape(), false, true)) {
-
-
- TopoDS_Shape current = support;
-
- if (!fuseShape.isNull()) {
- // We cannot wait to fuse a transformation with the support until all the transformations are done,
- // because the "support" potentially changes with every transformation, basically when checking intersection
- // above you need:
- // 1. The original support
- // 2. Any extra support gained by any previous transformation of any previous feature (multi-feature transform)
- // 3. Any extra support gained by any previous transformation of this feature (feature multi-trasform)
- //
- // Therefore, if the transformation succeeded, then we fuse it with the support now, before checking the intersection
- // of the next transformation.
-
- /*v_transformations.push_back(t);
- v_transformedShapes.push_back(mkTrf.Shape());*/
-
- // Note: Transformations that do not intersect the support are ignored in the overlap tests
-
- //insert scheme here.
- /*TopoDS_Compound compoundTool;
- std::vector<TopoDS_Shape> individualTools;
- divideTools(v_transformedShapes, individualTools, compoundTool);*/
-
- // Fuse/Cut the compounded transformed shapes with the support
- //TopoDS_Shape result;
-
- BRepAlgoAPI_Fuse mkFuse(current, shape);
- if (!mkFuse.IsDone())
- return new App::DocumentObjectExecReturn("Fusion with support failed", *o);
-
- if(Part::TopoShape(current).countSubShapes(TopAbs_SOLID)
- != Part::TopoShape(mkFuse.Shape()).countSubShapes(TopAbs_SOLID))
- {
-#ifdef FC_DEBUG // do not write this in release mode because a message appears already in the task view
- Base::Console().Warning("Transformed shape does not intersect support %s: Removed\n", (*o)->getNameInDocument());
+
+ shape.Move(*t);
+ shapes.emplace_back(shape);
+ builder.Add(compShape, shape);
+
+ overlapping = overlapping || (countSolids(TopoShape(origShape).fuse(shape))==1);
+
+ }
+
+ TopoDS_Shape toolShape;
+
+ if (overlapping) {
+
+#ifndef FC_DEBUG
+ Base::Console().Message("Transformed: Overlapping feature mode (fusing tool shapes)\n");
#endif
- nointersect_trsfms[*o].insert(t);
- continue;
- }
- // we have to get the solids (fuse sometimes creates compounds)
- current = this->getSolid(mkFuse.Shape());
- // lets check if the result is a solid
- if (current.IsNull())
- return new App::DocumentObjectExecReturn("Resulting shape is not a solid", *o);
-
- if (!cutShape.isNull()) {
- BRepBuilderAPI_Copy copy(cutShape.getShape());
- shape = copy.Shape();
- if (shape.IsNull())
- return new App::DocumentObjectExecReturn("Transformed: Linked shape object is empty");
-
- BRepBuilderAPI_Transform mkTrf(shape, *t, false); // No need to copy, now
- if (!mkTrf.IsDone())
- return new App::DocumentObjectExecReturn("Transformation failed", (*o));
- shape = mkTrf.Shape();
- }
- }
- if (!cutShape.isNull()) {
- BRepAlgoAPI_Cut mkCut(current, shape);
- if (!mkCut.IsDone())
- return new App::DocumentObjectExecReturn("Cut out of support failed", *o);
- current = mkCut.Shape();
- }
- support = current; // Use result of this operation for fuse/cut of next original
- } catch (Standard_Failure& e) {
- // Note: Ignoring this failure is probably pointless because if the intersection check fails, the later
- // fuse operation of the transformation result will also fail
-
- std::string msg("Transformation: Intersection check failed");
- if (e.GetMessageString() != NULL)
- msg += std::string(": '") + e.GetMessageString() + "'";
- return new App::DocumentObjectExecReturn(msg.c_str());
+
+ toolShape = TopoShape(origShape).fuse(shapes, Precision::Confusion());
+ } else {
+
+#ifndef FC_DEBUG
+ Base::Console().Message("Transformed: Non-Overlapping feature mode (compound of tool shapes)\n");
+#endif
+
+ toolShape = compShape;
+ }
+
+ if (!fuseShape.isNull()) {
+ std::unique_ptr<BRepAlgoAPI_BooleanOperation> mkBool(new BRepAlgoAPI_Fuse(current, toolShape));
+ if (!mkBool->IsDone()) {
+ std::stringstream error;
+ error << "Boolean operation failed";
+ return new App::DocumentObjectExecReturn(error.str());
+ }
+ current = mkBool->Shape();
+ } else {
+ std::unique_ptr<BRepAlgoAPI_BooleanOperation> mkBool(new BRepAlgoAPI_Cut(current, toolShape));
+ if (!mkBool->IsDone()) {
+ std::stringstream error;
+ error << "Boolean operation failed";
+ return new App::DocumentObjectExecReturn(error.str());
}
+ current = mkBool->Shape();
+ }
+ try {} catch (Standard_Failure& e) {
+ // Note: Ignoring this failure is probably pointless because if the intersection check fails, the later
+ // fuse operation of the transformation result will also fail
+
+ std::string msg("Transformation: Intersection check failed");
+ if (e.GetMessageString() != NULL)
+ msg += std::string(": '") + e.GetMessageString() + "'";
+ return new App::DocumentObjectExecReturn(msg.c_str());
}
+
+ support = current; // Use result of this operation for fuse/cut of next original
}
- support = refineShapeIfActive(support);
- for (rej_it_map::const_iterator it = nointersect_trsfms.begin(); it != nointersect_trsfms.end(); ++it)
- for (trsf_it::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2)
- rejected[it->first].push_back(**it2);
+ support = refineShapeIfActive(support);
int solidCount = countSolids(support);
if (solidCount > 1) {
- return new App::DocumentObjectExecReturn("Transformed: Result has multiple solids. This is not supported at this time.");
+ Base::Console().Warning("Transformed: Result has multiple solids. Only keeping the first.\n");
}
- this->Shape.setValue(getSolid(support));
+ this->Shape.setValue(getSolid(support)); // picking the first solid
- if (rejected.size() > 0) {
- return new App::DocumentObjectExecReturn("Transformation failed");
- }
+#ifndef FC_DEBUG
+ Base::Console().Message("Transformed: Elapsed CPU time: %f s\n", (std::clock() - start0 ) / (double)(CLOCKS_PER_SEC));
+#endif
return App::DocumentObject::StdReturn;
}
@@ -412,6 +376,9 @@ TopoDS_Shape Transformed::refineShapeIfActive(const TopoDS_Shape& oldShape) cons
try {
Part::BRepBuilderAPI_RefineModel mkRefine(oldShape);
TopoDS_Shape resShape = mkRefine.Shape();
+ if (!TopoShape(resShape).isClosed()) {
+ return oldShape;
+ }
return resShape;
}
catch (Standard_Failure&) {
From fecf9c2e8492ddab0858b4af23b56da36bff6f6a Mon Sep 17 00:00:00 2001
From: David Osterberg <davost@gmail.com>
Date: Tue, 23 Feb 2021 13:35:05 +0100
Subject: [PATCH] PartDesign: Transformed: Allow explict selection of overlap
mode
---
src/Mod/PartDesign/App/FeatureTransformed.cpp | 23 +++++++++++--------
src/Mod/PartDesign/App/FeatureTransformed.h | 8 +++++--
2 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/src/Mod/PartDesign/App/FeatureTransformed.cpp b/src/Mod/PartDesign/App/FeatureTransformed.cpp
index 9e638f32d7f..cd35a4e3e69 100644
--- a/src/Mod/PartDesign/App/FeatureTransformed.cpp
+++ b/src/Mod/PartDesign/App/FeatureTransformed.cpp
@@ -60,6 +60,8 @@ using namespace PartDesign;
namespace PartDesign {
+const char* Transformed::OverlapEnums[] = { "Detect", "Overlap mode", "Non-overlap mode", NULL};
+
PROPERTY_SOURCE(PartDesign::Transformed, PartDesign::Feature)
Transformed::Transformed()
@@ -69,6 +71,8 @@ Transformed::Transformed()
Placement.setStatus(App::Property::ReadOnly, true);
ADD_PROPERTY_TYPE(Refine,(0),"Part Design",(App::PropertyType)(App::Prop_None),"Refine shape (clean up redundant edges) after adding/subtracting");
+ ADD_PROPERTY_TYPE(Overlap, (0L), "Transform", App::Prop_None, "Feature overlapping behaviour");
+ Overlap.setEnums(OverlapEnums);
//init Refine property
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
@@ -201,6 +205,8 @@ short Transformed::mustExecute() const
App::DocumentObjectExecReturn *Transformed::execute(void)
{
+ std::string overlapMode = Overlap.getValueAsString();
+ bool overlapDetectionMode = overlapMode == "Detect";
#ifndef FC_DEBUG
std::clock_t start0;
@@ -302,27 +308,24 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
shapes.emplace_back(shape);
builder.Add(compShape, shape);
- overlapping = overlapping || (countSolids(TopoShape(origShape).fuse(shape))==1);
+ if (overlapDetectionMode)
+ overlapping = overlapping || (countSolids(TopoShape(origShape).fuse(shape))==1);
}
TopoDS_Shape toolShape;
- if (overlapping) {
-
#ifndef FC_DEBUG
+ if (overlapping || overlapMode == "Overlap mode")
Base::Console().Message("Transformed: Overlapping feature mode (fusing tool shapes)\n");
-#endif
-
- toolShape = TopoShape(origShape).fuse(shapes, Precision::Confusion());
- } else {
-
-#ifndef FC_DEBUG
+ else
Base::Console().Message("Transformed: Non-Overlapping feature mode (compound of tool shapes)\n");
#endif
+ if (overlapping || overlapMode == "Overlap mode")
+ toolShape = TopoShape(origShape).fuse(shapes, Precision::Confusion());
+ else
toolShape = compShape;
- }
if (!fuseShape.isNull()) {
std::unique_ptr<BRepAlgoAPI_BooleanOperation> mkBool(new BRepAlgoAPI_Fuse(current, toolShape));
diff --git a/src/Mod/PartDesign/App/FeatureTransformed.h b/src/Mod/PartDesign/App/FeatureTransformed.h
index ccb807ba433..b3ab64bc774 100644
--- a/src/Mod/PartDesign/App/FeatureTransformed.h
+++ b/src/Mod/PartDesign/App/FeatureTransformed.h
@@ -50,12 +50,13 @@ class PartDesignExport Transformed : public PartDesign::Feature
App::PropertyLinkList Originals;
App::PropertyBool Refine;
+ App::PropertyEnumeration Overlap;
/**
* Returns the BaseFeature property's object(if any) otherwise return first original,
* which serves as "Support" for old style workflows
* @param silent if couldn't determine the base feature and silent == true,
- * silently return a nullptr, otherwise throw Base::Exception.
+ * silently return a nullptr, otherwise throw Base::Exception.
* Default is false.
*/
virtual Part::Feature* getBaseObject(bool silent=false) const;
@@ -93,9 +94,12 @@ class PartDesignExport Transformed : public PartDesign::Feature
virtual void positionBySupport(void);
TopoDS_Shape refineShapeIfActive(const TopoDS_Shape&) const;
void divideTools(const std::vector<TopoDS_Shape> &toolsIn, std::vector<TopoDS_Shape> &individualsOut,
- TopoDS_Compound &compoundOut) const;
+ TopoDS_Compound &compoundOut) const;
rejectedMap rejected;
+
+private:
+ static const char* OverlapEnums[];
};
} //namespace PartDesign
From 8453d415150f289d36dfe4cbe6b91dfc512e82fe Mon Sep 17 00:00:00 2001
From: David Osterberg <davost@gmail.com>
Date: Sun, 28 Feb 2021 10:10:29 +0100
Subject: [PATCH] PartDesign: Transformed. Fix regression for Mirrored, and
multiple features
---
src/Mod/PartDesign/App/FeatureTransformed.cpp | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/Mod/PartDesign/App/FeatureTransformed.cpp b/src/Mod/PartDesign/App/FeatureTransformed.cpp
index cd35a4e3e69..d241e767bf8 100644
--- a/src/Mod/PartDesign/App/FeatureTransformed.cpp
+++ b/src/Mod/PartDesign/App/FeatureTransformed.cpp
@@ -296,7 +296,8 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
bool overlapping = false;
std::vector<gp_Trsf>::const_iterator t = transformations.begin();
- ++t; // Skip first transformation, which is always the identity transformation
+ //++t; // Skip first transformation, which is always the identity transformation
+ bool first = true;
for (; t != transformations.end(); ++t) {
// Make an explicit copy of the shape because the "true" parameter to BRepBuilderAPI_Transform
// seems to be pretty broken
@@ -304,13 +305,19 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
shape = copy.Shape();
- shape.Move(*t);
+ BRepBuilderAPI_Transform mkTrf(shape, *t, false); // No need to copy, now
+ if (!mkTrf.IsDone())
+ return new App::DocumentObjectExecReturn("Transformation failed", (*o));
+ shape = mkTrf.Shape();
+
shapes.emplace_back(shape);
builder.Add(compShape, shape);
- if (overlapDetectionMode)
+ if (overlapDetectionMode && !first)
overlapping = overlapping || (countSolids(TopoShape(origShape).fuse(shape))==1);
+ if (first)
+ first = false;
}
TopoDS_Shape toolShape;
From 3131b97aa88736ac628428a8ceb025d9b7a8a965 Mon Sep 17 00:00:00 2001
From: David Osterberg <davost@gmail.com>
Date: Sun, 28 Feb 2021 13:35:14 +0100
Subject: [PATCH] PartDesign: Transformed. Fix regression in preview
---
src/Mod/PartDesign/App/FeatureTransformed.cpp | 21 ++++-
src/Mod/PartDesign/App/FeatureTransformed.h | 10 +--
.../Gui/ViewProviderTransformed.cpp | 78 ++++++++-----------
3 files changed, 56 insertions(+), 53 deletions(-)
diff --git a/src/Mod/PartDesign/App/FeatureTransformed.cpp b/src/Mod/PartDesign/App/FeatureTransformed.cpp
index d241e767bf8..1acf6193b2a 100644
--- a/src/Mod/PartDesign/App/FeatureTransformed.cpp
+++ b/src/Mod/PartDesign/App/FeatureTransformed.cpp
@@ -296,7 +296,6 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
bool overlapping = false;
std::vector<gp_Trsf>::const_iterator t = transformations.begin();
- //++t; // Skip first transformation, which is always the identity transformation
bool first = true;
for (; t != transformations.end(); ++t) {
// Make an explicit copy of the shape because the "true" parameter to BRepBuilderAPI_Transform
@@ -372,6 +371,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
}
this->Shape.setValue(getSolid(support)); // picking the first solid
+ rejected = getRemainingSolids(support);
#ifndef FC_DEBUG
Base::Console().Message("Transformed: Elapsed CPU time: %f s\n", (std::clock() - start0 ) / (double)(CLOCKS_PER_SEC));
@@ -454,4 +454,23 @@ void Transformed::divideTools(const std::vector<TopoDS_Shape> &toolsIn, std::vec
}
}
+TopoDS_Shape Transformed::getRemainingSolids(const TopoDS_Shape& shape)
+{
+ BRep_Builder builder;
+ TopoDS_Compound compShape;
+ builder.MakeCompound(compShape);
+
+ if (shape.IsNull())
+ Standard_Failure::Raise("Shape is null");
+ TopExp_Explorer xp;
+ xp.Init(shape,TopAbs_SOLID);
+ xp.Next(); // skip the first
+
+ for (; xp.More(); xp.Next()) {
+ builder.Add(compShape, xp.Current());
+ }
+
+ return compShape;
+}
+
}
diff --git a/src/Mod/PartDesign/App/FeatureTransformed.h b/src/Mod/PartDesign/App/FeatureTransformed.h
index b3ab64bc774..e3068714976 100644
--- a/src/Mod/PartDesign/App/FeatureTransformed.h
+++ b/src/Mod/PartDesign/App/FeatureTransformed.h
@@ -83,20 +83,18 @@ class PartDesignExport Transformed : public PartDesign::Feature
short mustExecute() const;
//@}
- /** returns a list of the transformations that where rejected during the last execute
+ /** returns the compound of the shapes that were rejected during the last execute
* because they did not overlap with the support
*/
- typedef std::map<App::DocumentObject*, std::list<gp_Trsf> > rejectedMap;
- const rejectedMap getRejectedTransformations(void) { return rejected; }
+ TopoDS_Shape rejected;
protected:
void Restore(Base::XMLReader &reader);
virtual void positionBySupport(void);
TopoDS_Shape refineShapeIfActive(const TopoDS_Shape&) const;
void divideTools(const std::vector<TopoDS_Shape> &toolsIn, std::vector<TopoDS_Shape> &individualsOut,
- TopoDS_Compound &compoundOut) const;
-
- rejectedMap rejected;
+ TopoDS_Compound &compoundOut) const;
+ static TopoDS_Shape getRemainingSolids(const TopoDS_Shape&);
private:
static const char* OverlapEnums[];
diff --git a/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp b/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp
index 1f83738f164..0d402d0b71a 100644
--- a/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp
+++ b/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp
@@ -157,10 +157,15 @@ void ViewProviderTransformed::recomputeFeature(bool recompute)
PartDesign::Transformed* pcTransformed = static_cast<PartDesign::Transformed*>(getObject());
if(recompute || (pcTransformed->isError() || pcTransformed->mustExecute()))
pcTransformed->recomputeFeature(true);
- const PartDesign::Transformed::rejectedMap &rejected_trsf = pcTransformed->getRejectedTransformations();
+
unsigned rejected = 0;
- for (PartDesign::Transformed::rejectedMap::const_iterator r = rejected_trsf.begin(); r != rejected_trsf.end(); r++)
- rejected += r->second.size();
+ TopoDS_Shape cShape = pcTransformed->rejected;
+ TopExp_Explorer xp;
+ xp.Init(cShape, TopAbs_SOLID);
+ for (; xp.More(); xp.Next()) {
+ rejected++;
+ }
+
QString msg = QString::fromLatin1("%1");
if (rejected > 0) {
msg = QString::fromLatin1("<font color='orange'>%1<br/></font>\r\n%2");
@@ -192,21 +197,9 @@ void ViewProviderTransformed::recomputeFeature(bool recompute)
pcRejectedRoot ->removeChild(7);
}
- for (PartDesign::Transformed::rejectedMap::const_iterator o = rejected_trsf.begin(); o != rejected_trsf.end(); o++) {
- if (o->second.empty()) continue;
-
- Part::TopoShape fuseShape;
- Part::TopoShape cutShape;
- if ((o->first)->getTypeId().isDerivedFrom(PartDesign::FeatureAddSub::getClassTypeId())) {
- PartDesign::FeatureAddSub* feature = static_cast<PartDesign::FeatureAddSub*>(o->first);
- feature->getAddSubShape(fuseShape, cutShape);
- }
-
- if (fuseShape.isNull()) continue;
-
- // Display the rejected transformations in red
- TopoDS_Shape cShape(fuseShape.getShape());
+ // Display the rejected transformations in red
+ if (rejected > 0) {
try {
// calculating the deflection value
Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
@@ -333,41 +326,34 @@ void ViewProviderTransformed::recomputeFeature(bool recompute)
// counting up the per Face offsets
FaceNodeOffset += nbNodesInFace;
FaceTriaOffset += nbTriInFace;
- }
- // normalize all normals
- for (int i=0; i < nbrNodes; i++)
- norms[i].normalize();
-
- // end the editing of the nodes
- rejectedCoords ->point .finishEditing();
- rejectedNorms ->vector .finishEditing();
- rejectedFaceSet ->coordIndex .finishEditing();
-
- // fill in the transformation matrices
- SoMultipleCopy* rejectedTrfms = new SoMultipleCopy();
- rejectedTrfms->matrix.setNum((o->second).size());
- SbMatrix* mats = rejectedTrfms->matrix.startEditing();
-
- std::list<gp_Trsf>::const_iterator trsf = (o->second).begin();
- for (unsigned int i=0; i < (o->second).size(); i++,trsf++) {
- Base::Matrix4D mat;
- Part::TopoShape::convertToMatrix(*trsf,mat);
- mats[i] = convert(mat);
+
+ // normalize all normals
+ for (int i=0; i < nbrNodes; i++)
+ norms[i].normalize();
+
+ // end the editing of the nodes
+ rejectedCoords ->point .finishEditing();
+ rejectedNorms ->vector .finishEditing();
+ rejectedFaceSet ->coordIndex .finishEditing();
+
+ // fill in the transformation matrices
+ SoMultipleCopy* rejectedTrfms = new SoMultipleCopy();
+
+
+ rejectedTrfms->matrix.finishEditing();
+ rejectedTrfms->addChild(rejectedFaceSet);
+ SoSeparator* sep = new SoSeparator();
+ sep->addChild(rejectedCoords);
+ sep->addChild(rejectedNorms);
+ sep->addChild(rejectedTrfms);
+ pcRejectedRoot->addChild(sep);
}
- rejectedTrfms->matrix.finishEditing();
- rejectedTrfms->addChild(rejectedFaceSet);
- SoSeparator* sep = new SoSeparator();
- sep->addChild(rejectedCoords);
- sep->addChild(rejectedNorms);
- sep->addChild(rejectedTrfms);
- pcRejectedRoot->addChild(sep);
}
catch (...) {
Base::Console().Error("Cannot compute Inventor representation for the rejected transformations of shape of %s.\n",
- pcTransformed->getNameInDocument());
+ pcTransformed->getNameInDocument());
}
}
-
}
From 5b4c246944c72459016efff6ae903ac66c090991 Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Fri, 8 Oct 2021 22:32:26 +0200
Subject: [PATCH] PD: simplify code to display rejected shape and move it to
its own function
---
.../Gui/ViewProviderTransformed.cpp | 262 ++++++++----------
.../PartDesign/Gui/ViewProviderTransformed.h | 3 +
2 files changed, 119 insertions(+), 146 deletions(-)
diff --git a/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp b/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp
index 0d402d0b71a..0e3b7f0b068 100644
--- a/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp
+++ b/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp
@@ -55,6 +55,7 @@
#include <Gui/Application.h>
#include <Gui/Command.h>
#include <Mod/Part/App/TopoShape.h>
+#include <Mod/Part/App/Tools.h>
#include <Mod/PartDesign/App/FeatureTransformed.h>
#include <Mod/PartDesign/App/FeatureAddSub.h>
#include <Mod/PartDesign/App/FeatureMultiTransform.h>
@@ -198,162 +199,131 @@ void ViewProviderTransformed::recomputeFeature(bool recompute)
}
// Display the rejected transformations in red
-
if (rejected > 0) {
- try {
- // calculating the deflection value
- Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
- {
- Bnd_Box bounds;
- BRepBndLib::Add(cShape, bounds);
- bounds.SetGap(0.0);
- bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax);
- }
- Standard_Real deflection = ((xMax-xMin)+(yMax-yMin)+(zMax-zMin))/300.0 * Deviation.getValue();
+ showRejectedShape(cShape);
+ }
+}
- // create or use the mesh on the data structure
- // Note: This DOES have an effect on cShape
+void ViewProviderTransformed::showRejectedShape(TopoDS_Shape shape)
+{
+ try {
+ // calculating the deflection value
+ Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
+ {
+ Bnd_Box bounds;
+ BRepBndLib::Add(shape, bounds);
+ bounds.SetGap(0.0);
+ bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax);
+ }
+ Standard_Real deflection = ((xMax-xMin)+(yMax-yMin)+(zMax-zMin))/300.0 * Deviation.getValue();
+
+ // create or use the mesh on the data structure
+ // Note: This DOES have an effect on shape
#if OCC_VERSION_HEX >= 0x060600
- Standard_Real AngDeflectionRads = AngularDeflection.getValue() / 180.0 * M_PI;
- BRepMesh_IncrementalMesh(cShape,deflection,Standard_False,
- AngDeflectionRads,Standard_True);
+ Standard_Real AngDeflectionRads = AngularDeflection.getValue() / 180.0 * M_PI;
+ BRepMesh_IncrementalMesh(shape, deflection, Standard_False, AngDeflectionRads, Standard_True);
#else
- BRepMesh_IncrementalMesh(cShape,deflection);
+ BRepMesh_IncrementalMesh(shape, deflection);
#endif
- // We must reset the location here because the transformation data
- // are set in the placement property
- TopLoc_Location aLoc;
- cShape.Location(aLoc);
-
- // count triangles and nodes in the mesh
- int nbrTriangles=0, nbrNodes=0;
- TopExp_Explorer Ex;
- for (Ex.Init(cShape,TopAbs_FACE);Ex.More();Ex.Next()) {
- Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(TopoDS::Face(Ex.Current()), aLoc);
- // Note: we must also count empty faces
- if (!mesh.IsNull()) {
- nbrTriangles += mesh->NbTriangles();
- nbrNodes += mesh->NbNodes();
- }
+ // We must reset the location here because the transformation data
+ // are set in the placement property
+ TopLoc_Location aLoc;
+ shape.Location(aLoc);
+
+ // count triangles and nodes in the mesh
+ int nbrTriangles=0, nbrNodes=0;
+ TopExp_Explorer Ex;
+ for (Ex.Init(shape, TopAbs_FACE); Ex.More(); Ex.Next()) {
+ Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(TopoDS::Face(Ex.Current()), aLoc);
+ // Note: we must also count empty faces
+ if (!mesh.IsNull()) {
+ nbrTriangles += mesh->NbTriangles();
+ nbrNodes += mesh->NbNodes();
}
+ }
- // create memory for the nodes and indexes
- SoCoordinate3* rejectedCoords = new SoCoordinate3();
- rejectedCoords ->point .setNum(nbrNodes);
- SoNormal* rejectedNorms = new SoNormal();
- rejectedNorms ->vector .setNum(nbrNodes);
- SoIndexedFaceSet* rejectedFaceSet = new SoIndexedFaceSet();
- rejectedFaceSet ->coordIndex .setNum(nbrTriangles*4);
+ // create memory for the nodes and indexes
+ SoCoordinate3* rejectedCoords = new SoCoordinate3();
+ rejectedCoords ->point .setNum(nbrNodes);
+ SoNormal* rejectedNorms = new SoNormal();
+ rejectedNorms ->vector .setNum(nbrNodes);
+ SoIndexedFaceSet* rejectedFaceSet = new SoIndexedFaceSet();
+ rejectedFaceSet ->coordIndex .setNum(nbrTriangles*4);
+
+ // get the raw memory for fast fill up
+ SbVec3f* verts = rejectedCoords ->point .startEditing();
+ SbVec3f* norms = rejectedNorms ->vector .startEditing();
+ int32_t* index = rejectedFaceSet ->coordIndex .startEditing();
+
+ // preset the normal vector with null vector
+ for (int i=0; i < nbrNodes; i++)
+ norms[i]= SbVec3f(0.0,0.0,0.0);
+
+ int FaceNodeOffset=0,FaceTriaOffset=0;
+ for (Ex.Init(shape, TopAbs_FACE); Ex.More(); Ex.Next()) {
+ const TopoDS_Face &actFace = TopoDS::Face(Ex.Current());
+
+ // get triangulation
+ std::vector<gp_Pnt> points;
+ std::vector<Poly_Triangle> facets;
+ if (!Part::Tools::getTriangulation(actFace, points, facets))
+ continue;
+
+ // get normal per vertex
+ std::vector<gp_Vec> vertexnormals;
+ Part::Tools::getPointNormals(points, facets, vertexnormals);
+
+ // getting size of node and triangle array of this face
+ std::size_t nbNodesInFace = points.size();
+ std::size_t nbTriInFace = facets.size();
+
+ for (std::size_t i = 0; i < points.size(); i++) {
+ verts[FaceNodeOffset+i] = SbVec3f(points[i].X(), points[i].Y(), points[i].Z());
+ }
- // get the raw memory for fast fill up
- SbVec3f* verts = rejectedCoords ->point .startEditing();
- SbVec3f* norms = rejectedNorms ->vector .startEditing();
- int32_t* index = rejectedFaceSet ->coordIndex .startEditing();
+ for (std::size_t i = 0; i < vertexnormals.size(); i++) {
+ norms[FaceNodeOffset+i] = SbVec3f(vertexnormals[i].X(), vertexnormals[i].Y(), vertexnormals[i].Z());
+ }
- // preset the normal vector with null vector
- for (int i=0; i < nbrNodes; i++)
- norms[i]= SbVec3f(0.0,0.0,0.0);
-
- int ii = 0,FaceNodeOffset=0,FaceTriaOffset=0;
- for (Ex.Init(cShape, TopAbs_FACE); Ex.More(); Ex.Next(),ii++) {
- TopLoc_Location aLoc;
- const TopoDS_Face &actFace = TopoDS::Face(Ex.Current());
- // get the mesh of the shape
- Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(actFace,aLoc);
- if (mesh.IsNull()) continue;
-
- // getting the transformation of the shape/face
- gp_Trsf myTransf;
- Standard_Boolean identity = true;
- if (!aLoc.IsIdentity()) {
- identity = false;
- myTransf = aLoc.Transformation();
- }
-
- // getting size of node and triangle array of this face
- int nbNodesInFace = mesh->NbNodes();
- int nbTriInFace = mesh->NbTriangles();
- // check orientation
- TopAbs_Orientation orient = actFace.Orientation();
-
- // cycling through the poly mesh
- const Poly_Array1OfTriangle& Triangles = mesh->Triangles();
- const TColgp_Array1OfPnt& Nodes = mesh->Nodes();
- for (int g=1; g <= nbTriInFace; g++) {
- // Get the triangle
- Standard_Integer N1,N2,N3;
- Triangles(g).Get(N1,N2,N3);
-
- // change orientation of the triangle if the face is reversed
- if ( orient != TopAbs_FORWARD ) {
- Standard_Integer tmp = N1;
- N1 = N2;
- N2 = tmp;
- }
-
- // get the 3 points of this triangle
- gp_Pnt V1(Nodes(N1)), V2(Nodes(N2)), V3(Nodes(N3));
-
- // transform the vertices to the place of the face
- if (!identity) {
- V1.Transform(myTransf);
- V2.Transform(myTransf);
- V3.Transform(myTransf);
- }
-
- // calculating per vertex normals
- // Calculate triangle normal
- gp_Vec v1(V1.X(),V1.Y(),V1.Z()),v2(V2.X(),V2.Y(),V2.Z()),v3(V3.X(),V3.Y(),V3.Z());
- gp_Vec Normal = (v2-v1)^(v3-v1);
-
- // add the triangle normal to the vertex normal for all points of this triangle
- norms[FaceNodeOffset+N1-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z());
- norms[FaceNodeOffset+N2-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z());
- norms[FaceNodeOffset+N3-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z());
-
- // set the vertices
- verts[FaceNodeOffset+N1-1].setValue((float)(V1.X()),(float)(V1.Y()),(float)(V1.Z()));
- verts[FaceNodeOffset+N2-1].setValue((float)(V2.X()),(float)(V2.Y()),(float)(V2.Z()));
- verts[FaceNodeOffset+N3-1].setValue((float)(V3.X()),(float)(V3.Y()),(float)(V3.Z()));
-
- // set the index vector with the 3 point indexes and the end delimiter
- index[FaceTriaOffset*4+4*(g-1)] = FaceNodeOffset+N1-1;
- index[FaceTriaOffset*4+4*(g-1)+1] = FaceNodeOffset+N2-1;
- index[FaceTriaOffset*4+4*(g-1)+2] = FaceNodeOffset+N3-1;
- index[FaceTriaOffset*4+4*(g-1)+3] = SO_END_FACE_INDEX;
- }
-
- // counting up the per Face offsets
- FaceNodeOffset += nbNodesInFace;
- FaceTriaOffset += nbTriInFace;
-
-
- // normalize all normals
- for (int i=0; i < nbrNodes; i++)
- norms[i].normalize();
-
- // end the editing of the nodes
- rejectedCoords ->point .finishEditing();
- rejectedNorms ->vector .finishEditing();
- rejectedFaceSet ->coordIndex .finishEditing();
-
- // fill in the transformation matrices
- SoMultipleCopy* rejectedTrfms = new SoMultipleCopy();
-
-
- rejectedTrfms->matrix.finishEditing();
- rejectedTrfms->addChild(rejectedFaceSet);
- SoSeparator* sep = new SoSeparator();
- sep->addChild(rejectedCoords);
- sep->addChild(rejectedNorms);
- sep->addChild(rejectedTrfms);
- pcRejectedRoot->addChild(sep);
+ // cycling through the poly mesh
+ for (std::size_t g=0; g < nbTriInFace; g++) {
+ // Get the triangle
+ Standard_Integer N1,N2,N3;
+ facets[g].Get(N1,N2,N3);
+
+ // set the index vector with the 3 point indexes and the end delimiter
+ index[FaceTriaOffset*4+4*g] = FaceNodeOffset+N1;
+ index[FaceTriaOffset*4+4*g+1] = FaceNodeOffset+N2;
+ index[FaceTriaOffset*4+4*g+2] = FaceNodeOffset+N3;
+ index[FaceTriaOffset*4+4*g+3] = SO_END_FACE_INDEX;
}
- }
- catch (...) {
- Base::Console().Error("Cannot compute Inventor representation for the rejected transformations of shape of %s.\n",
- pcTransformed->getNameInDocument());
+
+ // counting up the per Face offsets
+ FaceNodeOffset += nbNodesInFace;
+ FaceTriaOffset += nbTriInFace;
+
+ // normalize all normals
+ for (int i=0; i < nbrNodes; i++)
+ norms[i].normalize();
+
+ // end the editing of the nodes
+ rejectedCoords ->point .finishEditing();
+ rejectedNorms ->vector .finishEditing();
+ rejectedFaceSet ->coordIndex .finishEditing();
+
+ // fill in the transformation matrices
+ SoMultipleCopy* rejectedTrfms = new SoMultipleCopy();
+ rejectedTrfms->matrix.finishEditing();
+ rejectedTrfms->addChild(rejectedFaceSet);
+ SoSeparator* sep = new SoSeparator();
+ sep->addChild(rejectedCoords);
+ sep->addChild(rejectedNorms);
+ sep->addChild(rejectedTrfms);
+ pcRejectedRoot->addChild(sep);
}
}
+ catch (...) {
+ Base::Console().Error("Cannot compute Inventor representation for the rejected transformations of shape of %s.\n",
+ getObject()->getNameInDocument());
+ }
}
-
diff --git a/src/Mod/PartDesign/Gui/ViewProviderTransformed.h b/src/Mod/PartDesign/Gui/ViewProviderTransformed.h
index 50a72ca1aeb..ec4b8e12263 100644
--- a/src/Mod/PartDesign/Gui/ViewProviderTransformed.h
+++ b/src/Mod/PartDesign/Gui/ViewProviderTransformed.h
@@ -68,6 +68,9 @@ class PartDesignGuiExport ViewProviderTransformed : public ViewProvider
public:
void recomputeFeature(bool recompute=true);
QString getMessage() const {return diagMessage;}
+
+private:
+ void showRejectedShape(TopoDS_Shape shape);
};
From f55c46cc86344a6d7389156c015194f7d0fd2b63 Mon Sep 17 00:00:00 2001
From: wmayer <wmayer@users.sourceforge.net>
Date: Sat, 13 Mar 2021 14:47:39 +0100
Subject: [PATCH] PD: adjust unit test for mirrored offset that doesn't fail
any more
---
src/Mod/PartDesign/PartDesignTests/TestMirrored.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Mod/PartDesign/PartDesignTests/TestMirrored.py b/src/Mod/PartDesign/PartDesignTests/TestMirrored.py
index fd6b32a34f2..7faf0ffb971 100644
--- a/src/Mod/PartDesign/PartDesignTests/TestMirrored.py
+++ b/src/Mod/PartDesign/PartDesignTests/TestMirrored.py
@@ -69,7 +69,7 @@ def testMirroredPrimitiveCase(self):
self.Doc.recompute()
self.assertAlmostEqual(self.Mirrored.Shape.Volume, 2.0)
- def testMirroredOffsetFailureCase(self):
+ def testMirroredOffsetCase(self):
self.Body = self.Doc.addObject('PartDesign::Body','Body')
self.Rect = self.Doc.addObject('Sketcher::SketchObject','Rect')
self.Body.addObject(self.Rect)
@@ -85,7 +85,7 @@ def testMirroredOffsetFailureCase(self):
self.Mirrored.MirrorPlane = (self.Rect, ["H_Axis"])
self.Body.addObject(self.Mirrored)
self.Doc.recompute()
- self.assertIn("Invalid", self.Mirrored.State)
+ self.assertIn("Up-to-date", self.Mirrored.State)
def tearDown(self):
#closing doc