diff --git a/src/Mod/Mesh/App/AppMesh.cpp b/src/Mod/Mesh/App/AppMesh.cpp index 2dcdb0f382..3595849038 100644 --- a/src/Mod/Mesh/App/AppMesh.cpp +++ b/src/Mod/Mesh/App/AppMesh.cpp @@ -44,7 +44,8 @@ #include "MeshPy.h" -namespace Mesh { +namespace Mesh +{ extern PyObject* initModule(); } @@ -57,12 +58,12 @@ PyMOD_INIT_FUNC(Mesh) // NOTE: To finish the initialization of our own type objects we must // call PyType_Ready, otherwise we run into a segmentation fault, later on. // This function is responsible for adding inherited slots from a type's base class. - ParameterGrp::handle handle = App::GetApplication().GetParameterGroupByPath - ("User parameter:BaseApp/Preferences/Mod/Mesh"); + ParameterGrp::handle handle = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/Mod/Mesh"); ParameterGrp::handle asy = handle->GetGroup("Asymptote"); - MeshCore::MeshOutput::SetAsymptoteSize(asy->GetASCII("Width", "500"), - asy->GetASCII("Height")); + MeshCore::MeshOutput::SetAsymptoteSize(asy->GetASCII("Width", "500"), asy->GetASCII("Height")); + // clang-format off // add mesh elements Base::Interpreter().addType(&Mesh::MeshPointPy ::Type,meshModule,"MeshPoint"); Base::Interpreter().addType(&Mesh::EdgePy ::Type,meshModule,"Edge"); @@ -109,6 +110,7 @@ PyMOD_INIT_FUNC(Mesh) Mesh::Cone ::init(); Mesh::Torus ::init(); Mesh::Cube ::init(); + // clang-format on PyMOD_Return(meshModule); } diff --git a/src/Mod/Mesh/App/AppMeshPy.cpp b/src/Mod/Mesh/App/AppMeshPy.cpp index 2e01572cbc..9733d6122a 100644 --- a/src/Mod/Mesh/App/AppMeshPy.cpp +++ b/src/Mod/Mesh/App/AppMeshPy.cpp @@ -22,11 +22,17 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include +#include +#include +#include #endif +#include "Core/Approximation.h" +#include "Core/Evaluation.h" +#include "Core/Iterator.h" +#include "Core/MeshIO.h" +#include "Core/MeshKernel.h" +#include "WildMagic4/Wm4ContBox3.h" #include #include #include @@ -35,89 +41,77 @@ #include #include #include -#include "Core/Approximation.h" -#include "Core/Evaluation.h" -#include "Core/Iterator.h" -#include "Core/MeshIO.h" -#include "Core/MeshKernel.h" -#include "WildMagic4/Wm4ContBox3.h" -#include "MeshPy.h" #include "Exporter.h" #include "Importer.h" #include "Mesh.h" +#include "MeshPy.h" using namespace Mesh; using namespace MeshCore; -namespace Mesh { -class Module : public Py::ExtensionModule +namespace Mesh +{ +class Module: public Py::ExtensionModule { public: - Module() : Py::ExtensionModule("Mesh") + Module() + : Py::ExtensionModule("Mesh") { - add_varargs_method("read",&Module::read, - "Read a mesh from a file and returns a Mesh object." - ); - add_varargs_method("open",&Module::open, - "open(string)\n" - "Create a new document and a Mesh feature to load the file into\n" - "the document." - ); - add_varargs_method("insert",&Module::importer, - "insert(string|mesh,[string])\n" - "Load or insert a mesh into the given or active document." - ); - add_keyword_method("export",&Module::exporter, - "export(objects, filename, [tolerance=0.1, exportAmfCompressed=True])\n" - "Export a list of objects into a single file identified by filename.\n" - "tolerance is in mm and specifies the maximum acceptable deviation\n" - "between the specified objects and the exported mesh.\n" - "exportAmfCompressed specifies whether exported AMF files should be\n" - "compressed.\n" - ); - add_varargs_method("show",&Module::show, - "show(shape,[string]) -- Add the mesh to the active document or create one if no document exists." - ); - add_varargs_method("createBox",&Module::createBox, - "Create a solid mesh box" - ); - add_varargs_method("createPlane",&Module::createPlane, - "Create a mesh XY plane normal +Z" - ); - add_varargs_method("createSphere",&Module::createSphere, - "Create a tessellated sphere" - ); - add_varargs_method("createEllipsoid",&Module::createEllipsoid, - "Create a tessellated ellipsoid" - ); - add_varargs_method("createCylinder",&Module::createCylinder, - "Create a tessellated cylinder" - ); - add_varargs_method("createCone",&Module::createCone, - "Create a tessellated cone" - ); - add_varargs_method("createTorus",&Module::createTorus, - "Create a tessellated torus" - ); - add_varargs_method("calculateEigenTransform",&Module::calculateEigenTransform, - "calculateEigenTransform(seq(Base.Vector))\n" - "Calculates the eigen Transformation from a list of points.\n" - "calculate the point's local coordinate system with the center\n" - "of gravity as origin. The local coordinate system is computed\n" - "this way that u has minimum and w has maximum expansion.\n" - "The local coordinate system is right-handed.\n" - ); - add_varargs_method("polynomialFit",&Module::polynomialFit, - "polynomialFit(seq(Base.Vector)) -- Calculates a polynomial fit." - ); - add_varargs_method("minimumVolumeOrientedBox",&Module::minimumVolumeOrientedBox, + add_varargs_method("read", + &Module::read, + "Read a mesh from a file and returns a Mesh object."); + add_varargs_method("open", + &Module::open, + "open(string)\n" + "Create a new document and a Mesh feature to load the file into\n" + "the document."); + add_varargs_method("insert", + &Module::importer, + "insert(string|mesh,[string])\n" + "Load or insert a mesh into the given or active document."); + add_keyword_method("export", + &Module::exporter, + "export(objects, filename, [tolerance=0.1, exportAmfCompressed=True])\n" + "Export a list of objects into a single file identified by filename.\n" + "tolerance is in mm and specifies the maximum acceptable deviation\n" + "between the specified objects and the exported mesh.\n" + "exportAmfCompressed specifies whether exported AMF files should be\n" + "compressed.\n"); + add_varargs_method("show", + &Module::show, + "show(shape,[string]) -- Add the mesh to the active document or create " + "one if no document exists."); + add_varargs_method("createBox", &Module::createBox, "Create a solid mesh box"); + add_varargs_method("createPlane", &Module::createPlane, "Create a mesh XY plane normal +Z"); + add_varargs_method("createSphere", &Module::createSphere, "Create a tessellated sphere"); + add_varargs_method("createEllipsoid", + &Module::createEllipsoid, + "Create a tessellated ellipsoid"); + add_varargs_method("createCylinder", + &Module::createCylinder, + "Create a tessellated cylinder"); + add_varargs_method("createCone", &Module::createCone, "Create a tessellated cone"); + add_varargs_method("createTorus", &Module::createTorus, "Create a tessellated torus"); + add_varargs_method("calculateEigenTransform", + &Module::calculateEigenTransform, + "calculateEigenTransform(seq(Base.Vector))\n" + "Calculates the eigen Transformation from a list of points.\n" + "calculate the point's local coordinate system with the center\n" + "of gravity as origin. The local coordinate system is computed\n" + "this way that u has minimum and w has maximum expansion.\n" + "The local coordinate system is right-handed.\n"); + add_varargs_method("polynomialFit", + &Module::polynomialFit, + "polynomialFit(seq(Base.Vector)) -- Calculates a polynomial fit."); + add_varargs_method( + "minimumVolumeOrientedBox", + &Module::minimumVolumeOrientedBox, "minimumVolumeOrientedBox(seq(Base.Vector)) -- Calculates the minimum\n" "volume oriented box containing all points. The return value is a\n" "tuple of seven items:\n" - " center, u, v, w directions and the lengths of the three vectors.\n" - ); + " center, u, v, w directions and the lengths of the three vectors.\n"); initialize("The functions in this module allow working with mesh objects.\n" "A set of functions are provided for reading in registered mesh\n" "file formats to either a new or existing document.\n" @@ -131,23 +125,24 @@ public: } private: - Py::Object invoke_method_varargs(void *method_def, const Py::Tuple &args) override + Py::Object invoke_method_varargs(void* method_def, const Py::Tuple& args) override { try { return Py::ExtensionModule::invoke_method_varargs(method_def, args); } - catch (const Base::Exception &e) { + catch (const Base::Exception& e) { throw Py::RuntimeError(e.what()); } - catch (const std::exception &e) { + catch (const std::exception& e) { throw Py::RuntimeError(e.what()); } } Py::Object read(const Py::Tuple& args) { char* Name; - if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name)) + if (!PyArg_ParseTuple(args.ptr(), "et", "utf-8", &Name)) { throw Py::Exception(); + } std::string EncodedName = std::string(Name); PyMem_Free(Name); @@ -158,14 +153,15 @@ private: Py::Object open(const Py::Tuple& args) { char* Name; - if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name)) + if (!PyArg_ParseTuple(args.ptr(), "et", "utf-8", &Name)) { throw Py::Exception(); + } std::string EncodedName = std::string(Name); PyMem_Free(Name); // create new document and add Import feature - App::Document *pcDoc = App::GetApplication().newDocument(); + App::Document* pcDoc = App::GetApplication().newDocument(); Mesh::Importer import(pcDoc); import.load(EncodedName); @@ -175,14 +171,15 @@ private: Py::Object importer(const Py::Tuple& args) { char* Name; - char* DocName=nullptr; - if (!PyArg_ParseTuple(args.ptr(), "et|s","utf-8",&Name,&DocName)) + char* DocName = nullptr; + if (!PyArg_ParseTuple(args.ptr(), "et|s", "utf-8", &Name, &DocName)) { throw Py::Exception(); + } std::string EncodedName = std::string(Name); PyMem_Free(Name); - App::Document *pcDoc = nullptr; + App::Document* pcDoc = nullptr; if (DocName) { pcDoc = App::GetApplication().getDocument(DocName); } @@ -200,26 +197,35 @@ private: return Py::None(); } - Py::Object exporter(const Py::Tuple &args, const Py::Dict &keywds) + Py::Object exporter(const Py::Tuple& args, const Py::Dict& keywds) { - PyObject *objects; - char *fileNamePy; + PyObject* objects; + char* fileNamePy; // If tolerance is specified via python interface, use that. // If not, use the preference, if that exists, else default to 0.1mm. - auto hGrp( App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Mesh") ); - auto fTolerance( hGrp->GetFloat("MaxDeviationExport", 0.1f) ); + auto hGrp(App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/Mod/Mesh")); + auto fTolerance(hGrp->GetFloat("MaxDeviationExport", 0.1f)); - int exportAmfCompressed( hGrp->GetBool("ExportAmfCompressed", true) ); - bool export3mfModel( hGrp->GetBool("Export3mfModel", true) ); + int exportAmfCompressed(hGrp->GetBool("ExportAmfCompressed", true)); + bool export3mfModel(hGrp->GetBool("Export3mfModel", true)); - static const std::array kwList{"objectList", "filename", "tolerance", - "exportAmfCompressed", nullptr}; + static const std::array kwList {"objectList", + "filename", + "tolerance", + "exportAmfCompressed", + nullptr}; - if (!Base::Wrapped_ParseTupleAndKeywords(args.ptr(), keywds.ptr(), - "Oet|dp", - kwList, &objects, "utf-8", &fileNamePy, - &fTolerance, &exportAmfCompressed)) { + if (!Base::Wrapped_ParseTupleAndKeywords(args.ptr(), + keywds.ptr(), + "Oet|dp", + kwList, + &objects, + "utf-8", + &fileNamePy, + &fTolerance, + &exportAmfCompressed)) { throw Py::Exception(); } @@ -236,9 +242,9 @@ private: // collect all object types that can be exported as mesh std::vector objectList; for (const auto& it : list) { - PyObject *item = it.ptr(); + PyObject* item = it.ptr(); if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { - auto obj( static_cast(item)->getDocumentObjectPtr() ); + auto obj(static_cast(item)->getDocumentObjectPtr()); objectList.push_back(obj); } } @@ -247,28 +253,30 @@ private: throw Py::TypeError("None of the objects can be exported to a mesh file"); } - auto exportFormat( MeshOutput::GetFormat(outputFileName.c_str()) ); + auto exportFormat(MeshOutput::GetFormat(outputFileName.c_str())); std::unique_ptr exporter; if (exportFormat == MeshIO::AMF) { std::map meta; - meta["cad"] = App::Application::Config()["ExeName"] + " " + - App::Application::Config()["ExeVersion"]; + meta["cad"] = App::Application::Config()["ExeName"] + " " + + App::Application::Config()["ExeVersion"]; meta[App::Application::Config()["ExeName"] + "-buildRevisionHash"] = - App::Application::Config()["BuildRevisionHash"]; + App::Application::Config()["BuildRevisionHash"]; exporter = std::make_unique(outputFileName, meta, exportAmfCompressed); } else if (exportFormat == MeshIO::ThreeMF) { Extension3MFFactory::initialize(); - exporter = std::make_unique(outputFileName, Extension3MFFactory::createExtensions()); + exporter = std::make_unique(outputFileName, + Extension3MFFactory::createExtensions()); dynamic_cast(exporter.get())->setForceModel(export3mfModel); } else if (exportFormat != MeshIO::Undefined) { exporter = std::make_unique(outputFileName, exportFormat); } else { - std::string exStr("Can't determine mesh format from file name.\nPlease specify mesh format file extension: '"); + std::string exStr("Can't determine mesh format from file name.\nPlease specify mesh " + "format file extension: '"); exStr += outputFileName + "'"; throw Py::ValueError(exStr.c_str()); } @@ -277,23 +285,26 @@ private: exporter->addObject(it, fTolerance); } - exporter.reset(); // deletes Exporter, mesh file is written by destructor + exporter.reset(); // deletes Exporter, mesh file is written by destructor return Py::None(); } Py::Object show(const Py::Tuple& args) { - PyObject *pcObj; - char *name = "Mesh"; - if (!PyArg_ParseTuple(args.ptr(), "O!|s", &(MeshPy::Type), &pcObj, &name)) + PyObject* pcObj; + char* name = "Mesh"; + if (!PyArg_ParseTuple(args.ptr(), "O!|s", &(MeshPy::Type), &pcObj, &name)) { throw Py::Exception(); + } - App::Document *pcDoc = App::GetApplication().getActiveDocument(); - if (!pcDoc) + App::Document* pcDoc = App::GetApplication().getActiveDocument(); + if (!pcDoc) { pcDoc = App::GetApplication().newDocument(); + } MeshPy* pMesh = static_cast(pcObj); - Mesh::Feature *pcFeature = static_cast(pcDoc->addObject("Mesh::Feature", name)); + Mesh::Feature* pcFeature = + static_cast(pcDoc->addObject("Mesh::Feature", name)); Mesh::MeshObject* mo = pMesh->getMeshObjectPtr(); if (!mo) { throw Py::Exception(PyExc_ReferenceError, "object doesn't reference a valid mesh"); @@ -312,25 +323,26 @@ private: float width = 10.0f; float height = 10.0f; float edgelen = -1.0f; - if (PyArg_ParseTuple(args.ptr(), "|ffff",&length,&width,&height,&edgelen)) { - if (edgelen < 0.0f) + if (PyArg_ParseTuple(args.ptr(), "|ffff", &length, &width, &height, &edgelen)) { + if (edgelen < 0.0f) { mesh = MeshObject::createCube(length, width, height); - else + } + else { mesh = MeshObject::createCube(length, width, height, edgelen); + } break; } PyErr_Clear(); PyObject* box; - if (PyArg_ParseTuple(args.ptr(), "O!",&Base::BoundBoxPy::Type, &box)) { + if (PyArg_ParseTuple(args.ptr(), "O!", &Base::BoundBoxPy::Type, &box)) { Py::BoundingBox bbox(box, false); mesh = MeshObject::createCube(bbox.getValue()); break; } throw Py::TypeError("Must be real numbers or BoundBox"); - } - while (false); + } while (false); if (!mesh) { throw Py::RuntimeError("Creation of box failed"); } @@ -338,19 +350,25 @@ private: } Py::Object createPlane(const Py::Tuple& args) { - float x=1,y=0,z=0; - if (!PyArg_ParseTuple(args.ptr(), "|fff",&x,&y,&z)) + float x = 1, y = 0, z = 0; + if (!PyArg_ParseTuple(args.ptr(), "|fff", &x, &y, &z)) { throw Py::Exception(); + } - if (y==0) - y=x; + if (y == 0) { + y = x; + } - float hx = x/2.0f; - float hy = y/2.0f; + float hx = x / 2.0f; + float hy = y / 2.0f; std::vector TriaList; - TriaList.emplace_back(Base::Vector3f(-hx, -hy, 0.0),Base::Vector3f(hx, hy, 0.0),Base::Vector3f(-hx, hy, 0.0)); - TriaList.emplace_back(Base::Vector3f(-hx, -hy, 0.0),Base::Vector3f(hx, -hy, 0.0),Base::Vector3f(hx, hy, 0.0)); + TriaList.emplace_back(Base::Vector3f(-hx, -hy, 0.0), + Base::Vector3f(hx, hy, 0.0), + Base::Vector3f(-hx, hy, 0.0)); + TriaList.emplace_back(Base::Vector3f(-hx, -hy, 0.0), + Base::Vector3f(hx, -hy, 0.0), + Base::Vector3f(hx, hy, 0.0)); std::unique_ptr mesh(new MeshObject); mesh->addFacets(TriaList); @@ -360,8 +378,9 @@ private: { float radius = 5.0f; int sampling = 50; - if (!PyArg_ParseTuple(args.ptr(), "|fi",&radius,&sampling)) + if (!PyArg_ParseTuple(args.ptr(), "|fi", &radius, &sampling)) { throw Py::Exception(); + } MeshObject* mesh = MeshObject::createSphere(radius, sampling); if (!mesh) { @@ -374,8 +393,9 @@ private: float radius1 = 2.0f; float radius2 = 4.0f; int sampling = 50; - if (!PyArg_ParseTuple(args.ptr(), "|ffi",&radius1,&radius2,&sampling)) + if (!PyArg_ParseTuple(args.ptr(), "|ffi", &radius1, &radius2, &sampling)) { throw Py::Exception(); + } MeshObject* mesh = MeshObject::createEllipsoid(radius1, radius2, sampling); if (!mesh) { @@ -390,8 +410,15 @@ private: int closed = 1; float edgelen = 1.0f; int sampling = 50; - if (!PyArg_ParseTuple(args.ptr(), "|ffifi",&radius,&length,&closed,&edgelen,&sampling)) + if (!PyArg_ParseTuple(args.ptr(), + "|ffifi", + &radius, + &length, + &closed, + &edgelen, + &sampling)) { throw Py::Exception(); + } MeshObject* mesh = MeshObject::createCylinder(radius, length, closed, edgelen, sampling); if (!mesh) { @@ -407,8 +434,16 @@ private: int closed = 1; float edgelen = 1.0f; int sampling = 50; - if (!PyArg_ParseTuple(args.ptr(), "|fffifi",&radius1,&radius2,&len,&closed,&edgelen,&sampling)) + if (!PyArg_ParseTuple(args.ptr(), + "|fffifi", + &radius1, + &radius2, + &len, + &closed, + &edgelen, + &sampling)) { throw Py::Exception(); + } MeshObject* mesh = MeshObject::createCone(radius1, radius2, len, closed, edgelen, sampling); if (!mesh) { @@ -421,8 +456,9 @@ private: float radius1 = 10.0f; float radius2 = 2.0f; int sampling = 50; - if (!PyArg_ParseTuple(args.ptr(), "|ffi",&radius1,&radius2,&sampling)) + if (!PyArg_ParseTuple(args.ptr(), "|ffi", &radius1, &radius2, &sampling)) { throw Py::Exception(); + } MeshObject* mesh = MeshObject::createTorus(radius1, radius2, sampling); if (!mesh) { @@ -432,10 +468,11 @@ private: } Py::Object calculateEigenTransform(const Py::Tuple& args) { - PyObject *input; + PyObject* input; - if (!PyArg_ParseTuple(args.ptr(), "O",&input)) + if (!PyArg_ParseTuple(args.ptr(), "O", &input)) { throw Py::Exception(); + } if (!PySequence_Check(input)) { throw Py::TypeError("Input has to be a sequence of Base.Vector()"); @@ -452,20 +489,22 @@ private: for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { PyObject* value = (*it).ptr(); if (PyObject_TypeCheck(value, &(Base::VectorPy::Type))) { - Base::VectorPy *pcObject = static_cast(value); + Base::VectorPy* pcObject = static_cast(value); Base::Vector3d* val = pcObject->getVectorPtr(); - current_node.Set(float(val->x),float(val->y),float(val->z)); + current_node.Set(float(val->x), float(val->y), float(val->z)); vertices.push_back(current_node); } } MeshCore::MeshFacet aFacet; - aFacet._aulPoints[0] = 0;aFacet._aulPoints[1] = 1;aFacet._aulPoints[2] = 2; + aFacet._aulPoints[0] = 0; + aFacet._aulPoints[1] = 1; + aFacet._aulPoints[2] = 2; faces.push_back(aFacet); - //Fill the Kernel with the temp mesh structure and delete the current containers - aMesh.Adopt(vertices,faces); + // Fill the Kernel with the temp mesh structure and delete the current containers + aMesh.Adopt(vertices, faces); MeshCore::MeshEigensystem pca(aMesh); pca.Evaluate(); Base::Matrix4D Trafo = pca.Transform(); @@ -474,10 +513,11 @@ private: } Py::Object polynomialFit(const Py::Tuple& args) { - PyObject *input; + PyObject* input; - if (!PyArg_ParseTuple(args.ptr(), "O",&input)) + if (!PyArg_ParseTuple(args.ptr(), "O", &input)) { throw Py::Exception(); + } if (!PySequence_Check(input)) { throw Py::TypeError("Input has to be a sequence of Base.Vector()"); @@ -490,9 +530,9 @@ private: for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { PyObject* value = (*it).ptr(); if (PyObject_TypeCheck(value, &(Base::VectorPy::Type))) { - Base::VectorPy *pcObject = static_cast(value); + Base::VectorPy* pcObject = static_cast(value); Base::Vector3d* val = pcObject->getVectorPtr(); - point.Set(float(val->x),float(val->y),float(val->z)); + point.Set(float(val->x), float(val->y), float(val->z)); polyFit.AddPoint(point); } } @@ -503,8 +543,8 @@ private: dict.setItem(Py::String("Sigma"), Py::Float(fit)); // coefficients - double a,b,c,d,e,f; - polyFit.GetCoefficients(a,b,c,d,e,f); + double a, b, c, d, e, f; + polyFit.GetCoefficients(a, b, c, d, e, f); Py::Tuple p(6); p.setItem(0, Py::Float(a)); p.setItem(1, Py::Float(b)); @@ -520,17 +560,19 @@ private: for (std::vector::iterator it = local.begin(); it != local.end(); ++it) { double z = polyFit.Value(it->x, it->y); double d = it->z - z; - r.setItem(it-local.begin(), Py::Float(d)); + r.setItem(it - local.begin(), Py::Float(d)); } dict.setItem(Py::String("Residuals"), r); return dict; } - Py::Object minimumVolumeOrientedBox(const Py::Tuple& args) { - PyObject *input; + Py::Object minimumVolumeOrientedBox(const Py::Tuple& args) + { + PyObject* input; - if (!PyArg_ParseTuple(args.ptr(), "O",&input)) + if (!PyArg_ParseTuple(args.ptr(), "O", &input)) { throw Py::Exception(); + } if (!PySequence_Check(input)) { throw Py::TypeError("Input has to be a sequence of Base.Vector()"); @@ -542,7 +584,7 @@ private: for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { PyObject* value = (*it).ptr(); if (PyObject_TypeCheck(value, &(Base::VectorPy::Type))) { - Base::VectorPy *pcObject = static_cast(value); + Base::VectorPy* pcObject = static_cast(value); Base::Vector3d* val = pcObject->getVectorPtr(); Wm4::Vector3d pt; pt[0] = val->x; @@ -552,8 +594,9 @@ private: } } - if (points.size() < 4) + if (points.size() < 4) { throw Py::RuntimeError("Too few points"); + } Wm4::Box3d mobox = Wm4::ContMinBox(points.size(), &(points[0]), 0.001, Wm4::Query::QT_REAL); Py::Tuple result(7); @@ -592,4 +635,4 @@ PyObject* initModule() return Base::Interpreter().addModule(new Module); } -} // namespace Mesh +} // namespace Mesh diff --git a/src/Mod/Mesh/App/Core/Algorithm.cpp b/src/Mod/Mesh/App/Core/Algorithm.cpp index 149f218f68..36f2cccb64 100644 --- a/src/Mod/Mesh/App/Core/Algorithm.cpp +++ b/src/Mod/Mesh/App/Core/Algorithm.cpp @@ -23,7 +23,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include @@ -32,18 +32,20 @@ #include "Algorithm.h" #include "Approximation.h" #include "Elements.h" -#include "Iterator.h" #include "Grid.h" +#include "Iterator.h" #include "Triangulation.h" using namespace MeshCore; -using Base::BoundBox3f; using Base::BoundBox2d; +using Base::BoundBox3f; using Base::Polygon2d; -bool MeshAlgorithm::IsVertexVisible (const Base::Vector3f &rcVertex, const Base::Vector3f &rcView, const MeshFacetGrid &rclGrid) const +bool MeshAlgorithm::IsVertexVisible(const Base::Vector3f& rcVertex, + const Base::Vector3f& rcView, + const MeshFacetGrid& rclGrid) const { const float fMaxDistance = 0.001F; Base::Vector3f cDirection = rcVertex - rcView; @@ -64,17 +66,22 @@ bool MeshAlgorithm::IsVertexVisible (const Base::Vector3f &rcVertex, const Base: } } - return true; // no facet between the two points + return true; // no facet between the two points } -bool MeshAlgorithm::NearestFacetOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, Base::Vector3f &rclRes, - FacetIndex &rulFacet) const +bool MeshAlgorithm::NearestFacetOnRay(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + Base::Vector3f& rclRes, + FacetIndex& rulFacet) const { return NearestFacetOnRay(rclPt, rclDir, Mathf::PI, rclRes, rulFacet); } -bool MeshAlgorithm::NearestFacetOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, float fMaxAngle, - Base::Vector3f &rclRes, FacetIndex &rulFacet) const +bool MeshAlgorithm::NearestFacetOnRay(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + float fMaxAngle, + Base::Vector3f& rclRes, + FacetIndex& rulFacet) const { Base::Vector3f clProj; Base::Vector3f clRes; @@ -82,35 +89,38 @@ bool MeshAlgorithm::NearestFacetOnRay (const Base::Vector3f &rclPt, const Base:: FacetIndex ulInd = 0; // slow execution with no grid - MeshFacetIterator clFIter(_rclMesh); + MeshFacetIterator clFIter(_rclMesh); for (clFIter.Init(); clFIter.More(); clFIter.Next()) { if (clFIter->Foraminate(rclPt, rclDir, clRes, fMaxAngle)) { if (!bSol) { // first solution - bSol = true; + bSol = true; clProj = clRes; - ulInd = clFIter.Position(); + ulInd = clFIter.Position(); } else { // is closer to the point if ((clRes - rclPt).Length() < (clProj - rclPt).Length()) { clProj = clRes; - ulInd = clFIter.Position(); + ulInd = clFIter.Position(); } } } } if (bSol) { - rclRes = clProj; + rclRes = clProj; rulFacet = ulInd; } return bSol; } -bool MeshAlgorithm::NearestFacetOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, const MeshFacetGrid &rclGrid, - Base::Vector3f &rclRes, FacetIndex &rulFacet) const +bool MeshAlgorithm::NearestFacetOnRay(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + const MeshFacetGrid& rclGrid, + Base::Vector3f& rclRes, + FacetIndex& rulFacet) const { std::vector aulFacets; MeshGridIterator clGridIter(rclGrid); @@ -132,12 +142,16 @@ bool MeshAlgorithm::NearestFacetOnRay (const Base::Vector3f &rclPt, const Base:: return false; } -bool MeshAlgorithm::NearestFacetOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, float fMaxSearchArea, - const MeshFacetGrid &rclGrid, Base::Vector3f &rclRes, FacetIndex &rulFacet) const +bool MeshAlgorithm::NearestFacetOnRay(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + float fMaxSearchArea, + const MeshFacetGrid& rclGrid, + Base::Vector3f& rclRes, + FacetIndex& rulFacet) const { const float fMaxAngle = 1.75F; std::vector aulFacets; - MeshGridIterator clGridIter(rclGrid); + MeshGridIterator clGridIter(rclGrid); if (clGridIter.InitOnRay(rclPt, rclDir, fMaxSearchArea, aulFacets)) { if (!RayNearestField(rclPt, rclDir, aulFacets, rclRes, rulFacet, fMaxAngle)) { @@ -156,72 +170,81 @@ bool MeshAlgorithm::NearestFacetOnRay (const Base::Vector3f &rclPt, const Base:: return false; } -bool MeshAlgorithm::NearestFacetOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, - const std::vector &raulFacets, - Base::Vector3f &rclRes, FacetIndex &rulFacet) const +bool MeshAlgorithm::NearestFacetOnRay(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + const std::vector& raulFacets, + Base::Vector3f& rclRes, + FacetIndex& rulFacet) const { - Base::Vector3f clProj; - Base::Vector3f clRes; + Base::Vector3f clProj; + Base::Vector3f clRes; bool bSol = false; FacetIndex ulInd = 0; for (FacetIndex index : raulFacets) { MeshGeomFacet rclSFacet = _rclMesh.GetFacet(index); if (rclSFacet.Foraminate(rclPt, rclDir, clRes)) { - if (!bSol) {// first solution - bSol = true; + if (!bSol) { // first solution + bSol = true; clProj = clRes; - ulInd = index; + ulInd = index; } else { // is closer to the point if ((clRes - rclPt).Length() < (clProj - rclPt).Length()) { clProj = clRes; - ulInd = index; + ulInd = index; } } } } if (bSol) { - rclRes = clProj; + rclRes = clProj; rulFacet = ulInd; } return bSol; } -bool MeshAlgorithm::RayNearestField (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, const std::vector &raulFacets, - Base::Vector3f &rclRes, FacetIndex &rulFacet, float /*fMaxAngle*/) const +bool MeshAlgorithm::RayNearestField(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + const std::vector& raulFacets, + Base::Vector3f& rclRes, + FacetIndex& rulFacet, + float /*fMaxAngle*/) const { - Base::Vector3f clProj, clRes; + Base::Vector3f clProj, clRes; bool bSol = false; FacetIndex ulInd = 0; for (FacetIndex index : raulFacets) { - if (_rclMesh.GetFacet(index).Foraminate(rclPt, rclDir, clRes/*, fMaxAngle*/)) { - if (!bSol) { // first solution - bSol = true; + if (_rclMesh.GetFacet(index).Foraminate(rclPt, rclDir, clRes /*, fMaxAngle*/)) { + if (!bSol) { // first solution + bSol = true; clProj = clRes; - ulInd = index; + ulInd = index; } else { // is closer to the point if ((clRes - rclPt).Length() < (clProj - rclPt).Length()) { clProj = clRes; - ulInd = index; + ulInd = index; } } } } if (bSol) { - rclRes = clProj; + rclRes = clProj; rulFacet = ulInd; } return bSol; } -bool MeshAlgorithm::FirstFacetToVertex(const Base::Vector3f &rPt, float fMaxDistance, const MeshFacetGrid &rGrid, FacetIndex &uIndex) const +bool MeshAlgorithm::FirstFacetToVertex(const Base::Vector3f& rPt, + float fMaxDistance, + const MeshFacetGrid& rGrid, + FacetIndex& uIndex) const { const float fEps = 0.001f; @@ -262,11 +285,12 @@ float MeshAlgorithm::GetAverageEdgeLength() const float fLen = 0.0f; MeshFacetIterator cF(_rclMesh); for (cF.Init(); cF.More(); cF.Next()) { - for (int i=0; i<3; i++) - fLen += Base::Distance(cF->_aclPoints[i], cF->_aclPoints[(i+1)%3]); + for (int i = 0; i < 3; i++) { + fLen += Base::Distance(cF->_aclPoints[i], cF->_aclPoints[(i + 1) % 3]); + } } - fLen = fLen / (3.0f * _rclMesh.CountFacets() ); + fLen = fLen / (3.0f * _rclMesh.CountFacets()); return fLen; } @@ -275,8 +299,9 @@ float MeshAlgorithm::GetMinimumEdgeLength() const float fLen = FLOAT_MAX; MeshFacetIterator cF(_rclMesh); for (cF.Init(); cF.More(); cF.Next()) { - for (int i=0; i<3; i++) - fLen = std::min(fLen, Base::Distance(cF->_aclPoints[i], cF->_aclPoints[(i+1)%3])); + for (int i = 0; i < 3; i++) { + fLen = std::min(fLen, Base::Distance(cF->_aclPoints[i], cF->_aclPoints[(i + 1) % 3])); + } } return fLen; @@ -287,8 +312,9 @@ float MeshAlgorithm::GetMaximumEdgeLength() const float fLen = 0.0f; MeshFacetIterator cF(_rclMesh); for (cF.Init(); cF.More(); cF.Next()) { - for (int i=0; i<3; i++) - fLen = std::max(fLen, Base::Distance(cF->_aclPoints[i], cF->_aclPoints[(i+1)%3])); + for (int i = 0; i < 3; i++) { + fLen = std::max(fLen, Base::Distance(cF->_aclPoints[i], cF->_aclPoints[(i + 1) % 3])); + } } return fLen; @@ -305,78 +331,84 @@ Base::Vector3f MeshAlgorithm::GetGravityPoint() const return center / static_cast(_rclMesh.CountPoints()); } -void MeshAlgorithm::GetMeshBorders (std::list > &rclBorders) const +void MeshAlgorithm::GetMeshBorders(std::list>& rclBorders) const { std::vector aulAllFacets(_rclMesh.CountFacets()); FacetIndex k = 0; - for (FacetIndex & index : aulAllFacets) + for (FacetIndex& index : aulAllFacets) { index = k++; + } GetFacetBorders(aulAllFacets, rclBorders); } -void MeshAlgorithm::GetMeshBorders (std::list > &rclBorders) const +void MeshAlgorithm::GetMeshBorders(std::list>& rclBorders) const { std::vector aulAllFacets(_rclMesh.CountFacets()); FacetIndex k = 0; - for (FacetIndex & index : aulAllFacets) + for (FacetIndex& index : aulAllFacets) { index = k++; + } GetFacetBorders(aulAllFacets, rclBorders, true); } -void MeshAlgorithm::GetFacetBorders (const std::vector &raulInd, std::list > &rclBorders) const +void MeshAlgorithm::GetFacetBorders(const std::vector& raulInd, + std::list>& rclBorders) const { - const MeshPointArray &rclPAry = _rclMesh._aclPointArray; - std::list > aulBorders; + const MeshPointArray& rclPAry = _rclMesh._aclPointArray; + std::list> aulBorders; - GetFacetBorders (raulInd, aulBorders, true); - for (const auto & border : aulBorders) - { - std::vector boundary; - boundary.reserve( border.size() ); + GetFacetBorders(raulInd, aulBorders, true); + for (const auto& border : aulBorders) { + std::vector boundary; + boundary.reserve(border.size()); - for (PointIndex jt : border) - boundary.push_back(rclPAry[jt]); + for (PointIndex jt : border) { + boundary.push_back(rclPAry[jt]); + } - rclBorders.push_back( boundary ); - } + rclBorders.push_back(boundary); + } } -void MeshAlgorithm::GetFacetBorders (const std::vector &raulInd, - std::list > &rclBorders, - bool ignoreOrientation) const +void MeshAlgorithm::GetFacetBorders(const std::vector& raulInd, + std::list>& rclBorders, + bool ignoreOrientation) const { - const MeshFacetArray &rclFAry = _rclMesh._aclFacetArray; + const MeshFacetArray& rclFAry = _rclMesh._aclFacetArray; // mark all facets that are in the indices list ResetFacetFlag(MeshFacet::VISIT); - for (FacetIndex it : raulInd) + for (FacetIndex it : raulInd) { rclFAry[it].SetFlag(MeshFacet::VISIT); + } // collect all boundary edges (unsorted) - std::list > aclEdges; + std::list> aclEdges; for (FacetIndex it : raulInd) { - const MeshFacet &rclFacet = rclFAry[it]; + const MeshFacet& rclFacet = rclFAry[it]; for (unsigned short i = 0; i < 3; i++) { FacetIndex ulNB = rclFacet._aulNeighbours[i]; if (ulNB != FACET_INDEX_MAX) { - if (rclFAry[ulNB].IsFlag(MeshFacet::VISIT)) + if (rclFAry[ulNB].IsFlag(MeshFacet::VISIT)) { continue; + } } aclEdges.push_back(rclFacet.GetEdge(i)); } } - if (aclEdges.empty()) - return; // no borders found (=> solid) + if (aclEdges.empty()) { + return; // no borders found (=> solid) + } // search for edges in the unsorted list PointIndex ulFirst, ulLast; std::list clBorder; ulFirst = aclEdges.begin()->first; - ulLast = aclEdges.begin()->second; + ulLast = aclEdges.begin()->second; aclEdges.erase(aclEdges.begin()); clBorder.push_back(ulFirst); @@ -384,7 +416,7 @@ void MeshAlgorithm::GetFacetBorders (const std::vector &raulInd, while (!aclEdges.empty()) { // get adjacent edge - std::list >::iterator pEI; + std::list>::iterator pEI; for (pEI = aclEdges.begin(); pEI != aclEdges.end(); ++pEI) { if (pEI->first == ulLast) { ulLast = pEI->second; @@ -429,7 +461,7 @@ void MeshAlgorithm::GetFacetBorders (const std::vector &raulInd, if (!aclEdges.empty()) { // start new boundary ulFirst = aclEdges.begin()->first; - ulLast = aclEdges.begin()->second; + ulLast = aclEdges.begin()->second; aclEdges.erase(aclEdges.begin()); clBorder.push_back(ulFirst); clBorder.push_back(ulLast); @@ -440,44 +472,47 @@ void MeshAlgorithm::GetFacetBorders (const std::vector &raulInd, void MeshAlgorithm::GetFacetBorder(FacetIndex uFacet, std::list& rBorder) const { - const MeshFacetArray &rFAry = _rclMesh._aclFacetArray; - std::list > openEdges; - if (uFacet >= rFAry.size()) + const MeshFacetArray& rFAry = _rclMesh._aclFacetArray; + std::list> openEdges; + if (uFacet >= rFAry.size()) { return; + } // add the open edge to the beginning of the list MeshFacetArray::_TConstIterator face = rFAry.begin() + uFacet; - for (unsigned short i = 0; i < 3; i++) - { - if (face->_aulNeighbours[i] == FACET_INDEX_MAX) + for (unsigned short i = 0; i < 3; i++) { + if (face->_aulNeighbours[i] == FACET_INDEX_MAX) { openEdges.push_back(face->GetEdge(i)); + } } - if (openEdges.empty()) - return; // facet is not a border facet + if (openEdges.empty()) { + return; // facet is not a border facet + } - for (MeshFacetArray::_TConstIterator it = rFAry.begin(); it != rFAry.end(); ++it) - { - if (it == face) + for (MeshFacetArray::_TConstIterator it = rFAry.begin(); it != rFAry.end(); ++it) { + if (it == face) { continue; - for (unsigned short i = 0; i < 3; i++) - { - if (it->_aulNeighbours[i] == FACET_INDEX_MAX) + } + for (unsigned short i = 0; i < 3; i++) { + if (it->_aulNeighbours[i] == FACET_INDEX_MAX) { openEdges.push_back(it->GetEdge(i)); + } } } SplitBoundaryFromOpenEdges(openEdges, rBorder); } -void MeshAlgorithm::GetFacetsBorders(const std::vector& uFacets, std::list >& rBorders) const +void MeshAlgorithm::GetFacetsBorders(const std::vector& uFacets, + std::list>& rBorders) const { ResetFacetFlag(MeshFacet::TMP0); SetFacetsFlag(uFacets, MeshFacet::TMP0); ResetPointFlag(MeshPoint::TMP0); - const MeshFacetArray &rFAry = _rclMesh._aclFacetArray; - const MeshPointArray &rPAry = _rclMesh._aclPointArray; - std::list > openEdges; + const MeshFacetArray& rFAry = _rclMesh._aclFacetArray; + const MeshPointArray& rPAry = _rclMesh._aclPointArray; + std::list> openEdges; // add the open edge to the beginning of the list for (auto it : uFacets) { @@ -493,26 +528,31 @@ void MeshAlgorithm::GetFacetsBorders(const std::vector& uFacets, std } } - if (openEdges.empty()) - return; // none of the facets are border facets + if (openEdges.empty()) { + return; // none of the facets are border facets + } - for (const auto & it : rFAry) { - if (it.IsFlag(MeshFacet::TMP0)) + for (const auto& it : rFAry) { + if (it.IsFlag(MeshFacet::TMP0)) { continue; + } for (int i = 0; i < 3; i++) { - if (it._aulNeighbours[i] == FACET_INDEX_MAX) + if (it._aulNeighbours[i] == FACET_INDEX_MAX) { openEdges.push_back(it.GetEdge(i)); + } } } // if the first element is not an edge of "uFacets" then give up while (!openEdges.empty()) { PointIndex first = openEdges.begin()->first; - PointIndex second = openEdges.begin()->second; - if (!rPAry[first].IsFlag(MeshPoint::TMP0)) + PointIndex second = openEdges.begin()->second; + if (!rPAry[first].IsFlag(MeshPoint::TMP0)) { break; - if (!rPAry[second].IsFlag(MeshPoint::TMP0)) + } + if (!rPAry[second].IsFlag(MeshPoint::TMP0)) { break; + } std::list boundary; SplitBoundaryFromOpenEdges(openEdges, boundary); @@ -520,14 +560,17 @@ void MeshAlgorithm::GetFacetsBorders(const std::vector& uFacets, std } } -void MeshAlgorithm::SplitBoundaryFromOpenEdges(std::list >& openEdges, std::list& boundary) const +void MeshAlgorithm::SplitBoundaryFromOpenEdges( + std::list>& openEdges, + std::list& boundary) const { // Start with the edge that is associated to uFacet - if (openEdges.empty()) + if (openEdges.empty()) { return; + } PointIndex ulFirst = openEdges.begin()->first; - PointIndex ulLast = openEdges.begin()->second; + PointIndex ulLast = openEdges.begin()->second; openEdges.erase(openEdges.begin()); boundary.push_back(ulFirst); @@ -535,7 +578,7 @@ void MeshAlgorithm::SplitBoundaryFromOpenEdges(std::list >::iterator pEI; + std::list>::iterator pEI; for (pEI = openEdges.begin(); pEI != openEdges.end(); ++pEI) { if (pEI->first == ulLast) { ulLast = pEI->second; @@ -554,28 +597,29 @@ void MeshAlgorithm::SplitBoundaryFromOpenEdges(std::list >& aBorders ) +void MeshAlgorithm::SplitBoundaryLoops(std::list>& aBorders) { // Count the number of open edges for each point std::map openPointDegree; - for (const auto & jt : _rclMesh._aclFacetArray) { - for (int i=0; i<3; i++) { + for (const auto& jt : _rclMesh._aclFacetArray) { + for (int i = 0; i < 3; i++) { if (jt._aulNeighbours[i] == FACET_INDEX_MAX) { openPointDegree[jt._aulPoints[i]]++; - openPointDegree[jt._aulPoints[(i+1)%3]]++; + openPointDegree[jt._aulPoints[(i + 1) % 3]]++; } } } // go through all boundaries and split them if needed - std::list > aSplitBorders; - for (const auto & aBorder : aBorders) { - bool split=false; + std::list> aSplitBorders; + for (const auto& aBorder : aBorders) { + bool split = false; for (auto jt : aBorder) { // two (or more) boundaries meet in one non-manifold point if (openPointDegree[jt] > 2) { @@ -584,17 +628,19 @@ void MeshAlgorithm::SplitBoundaryLoops( std::list >& aBo } } - if (!split) - aSplitBorders.push_back( aBorder ); - else - SplitBoundaryLoops( aBorder, aSplitBorders ); + if (!split) { + aSplitBorders.push_back(aBorder); + } + else { + SplitBoundaryLoops(aBorder, aSplitBorders); + } } aBorders = aSplitBorders; } void MeshAlgorithm::SplitBoundaryLoops(const std::vector& rBound, - std::list >& aBorders) + std::list>& aBorders) { std::map aPtDegree; std::vector cBound; @@ -620,41 +666,51 @@ void MeshAlgorithm::SplitBoundaryLoops(const std::vector& rBound, bool MeshAlgorithm::FillupHole(const std::vector& boundary, AbstractPolygonTriangulator& cTria, - MeshFacetArray& rFaces, MeshPointArray& rPoints, - int level, const MeshRefPointToFacets* pP2FStructure) const + MeshFacetArray& rFaces, + MeshPointArray& rPoints, + int level, + const MeshRefPointToFacets* pP2FStructure) const { if (boundary.front() == boundary.back()) { // first and last vertex are identical - if (boundary.size() < 4) - return false; // something strange + if (boundary.size() < 4) { + return false; // something strange + } } else if (boundary.size() < 3) { - return false; // something strange + return false; // something strange } // Get a facet as reference coordinate system MeshGeomFacet rTriangle; MeshFacet rFace; PointIndex refPoint0 = *(boundary.begin()); - PointIndex refPoint1 = *(boundary.begin()+1); + PointIndex refPoint1 = *(boundary.begin() + 1); if (pP2FStructure) { const std::set& ring1 = (*pP2FStructure)[refPoint0]; const std::set& ring2 = (*pP2FStructure)[refPoint1]; std::vector f_int; - std::set_intersection(ring1.begin(), ring1.end(), ring2.begin(), ring2.end(), - std::back_insert_iterator >(f_int)); - if (f_int.size() != 1) - return false; // error, this must be an open edge! + std::set_intersection(ring1.begin(), + ring1.end(), + ring2.begin(), + ring2.end(), + std::back_insert_iterator>(f_int)); + if (f_int.size() != 1) { + return false; // error, this must be an open edge! + } rFace = _rclMesh._aclFacetArray[f_int.front()]; rTriangle = _rclMesh.GetFacet(rFace); } else { bool ready = false; - for (MeshFacetArray::_TConstIterator it = _rclMesh._aclFacetArray.begin(); it != _rclMesh._aclFacetArray.end(); ++it) { - for (int i=0; i<3; i++) { - if (((it->_aulPoints[i] == refPoint0) && (it->_aulPoints[(i+1)%3] == refPoint1)) || - ((it->_aulPoints[i] == refPoint1) && (it->_aulPoints[(i+1)%3] == refPoint0))) { + for (MeshFacetArray::_TConstIterator it = _rclMesh._aclFacetArray.begin(); + it != _rclMesh._aclFacetArray.end(); + ++it) { + for (int i = 0; i < 3; i++) { + if (((it->_aulPoints[i] == refPoint0) && (it->_aulPoints[(i + 1) % 3] == refPoint1)) + || ((it->_aulPoints[i] == refPoint1) + && (it->_aulPoints[(i + 1) % 3] == refPoint0))) { rFace = *it; rTriangle = _rclMesh.GetFacet(*it); ready = true; @@ -662,8 +718,9 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, } } - if (ready) + if (ready) { break; + } } } @@ -682,9 +739,10 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, rPoints.pop_back(); } - // There is no easy way to check whether the boundary is interior (a hole) or exterior before performing the triangulation. - // Afterwards we can compare the normals of the created triangles with the z-direction of our local coordinate system. - // If the scalar product is positive it was a hole, otherwise not. + // There is no easy way to check whether the boundary is interior (a hole) or exterior before + // performing the triangulation. Afterwards we can compare the normals of the created triangles + // with the z-direction of our local coordinate system. If the scalar product is positive it was + // a hole, otherwise not. cTria.SetPolygon(polygon); cTria.SetIndices(bounds); @@ -704,18 +762,18 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, // get the facets and add the additional points to the array rFaces.insert(rFaces.end(), cTria.GetFacets().begin(), cTria.GetFacets().end()); std::vector newVertices = cTria.AddedPoints(); - for (const auto & vertex : newVertices) { + for (const auto& vertex : newVertices) { rPoints.push_back(vertex); } - // Unfortunately, some algorithms do not care about the orientation of the polygon so we cannot rely on the normal - // criterion to decide whether it's a hole or not. + // Unfortunately, some algorithms do not care about the orientation of the polygon so we + // cannot rely on the normal criterion to decide whether it's a hole or not. // std::vector faces = cTria.GetFacets(); - // Special case handling for a hole with three edges: the resulting facet might be coincident with the - // reference facet - if (faces.size()==1){ + // Special case handling for a hole with three edges: the resulting facet might be + // coincident with the reference facet + if (faces.size() == 1) { MeshFacet first = faces.front(); if (cTria.NeedsReindexing()) { first._aulPoints[0] = boundary[first._aulPoints[0]]; @@ -740,7 +798,7 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, refPoint1 = 1; } if (ref_side < USHRT_MAX) { - for (const auto & face : faces) { + for (const auto& face : faces) { tri_side = face.Side(refPoint0, refPoint1); if (tri_side < USHRT_MAX) { facet = face; @@ -751,8 +809,11 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, // in case the reference facet has not an open edge print a log message if (ref_side == USHRT_MAX || tri_side == USHRT_MAX) { - Base::Console().Log("MeshAlgorithm::FillupHole: Expected open edge for facet <%d, %d, %d>\n", - rFace._aulPoints[0], rFace._aulPoints[1], rFace._aulPoints[2]); + Base::Console().Log( + "MeshAlgorithm::FillupHole: Expected open edge for facet <%d, %d, %d>\n", + rFace._aulPoints[0], + rFace._aulPoints[1], + rFace._aulPoints[2]); rFaces.clear(); rPoints.clear(); cTria.Discard(); @@ -764,15 +825,18 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, triangle = cTria.GetTriangle(rPoints, facet); TriangulationVerifier* verifier = cTria.GetVerifier(); - if (!verifier) + if (!verifier) { return true; + } // Now we have two adjacent triangles which we check for overlaps. - // Therefore we build a separation plane that must separate the two diametrically opposed points. - Base::Vector3f planeNormal = rTriangle.GetNormal() % (rTriangle._aclPoints[(ref_side+1)%3]-rTriangle._aclPoints[ref_side]); - Base::Vector3f planeBase = rTriangle._aclPoints[ref_side%3]; - Base::Vector3f ref_point = rTriangle._aclPoints[(ref_side+2)%3]; - Base::Vector3f tri_point = triangle._aclPoints[(tri_side+2)%3]; + // Therefore we build a separation plane that must separate the two diametrically opposed + // points. + Base::Vector3f planeNormal = rTriangle.GetNormal() + % (rTriangle._aclPoints[(ref_side + 1) % 3] - rTriangle._aclPoints[ref_side]); + Base::Vector3f planeBase = rTriangle._aclPoints[ref_side % 3]; + Base::Vector3f ref_point = rTriangle._aclPoints[(ref_side + 2) % 3]; + Base::Vector3f tri_point = triangle._aclPoints[(tri_side + 2) % 3]; if (!verifier->Accept(planeNormal, planeBase, ref_point, tri_point)) { rFaces.clear(); @@ -783,8 +847,9 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, // we know to have filled a polygon, now check for the orientation if (verifier->MustFlip(triangle.GetNormal(), rTriangle.GetNormal())) { - for (auto & rFace : rFaces) + for (auto& rFace : rFaces) { rFace.FlipNormal(); + } } #endif @@ -794,97 +859,119 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, return false; } -void MeshAlgorithm::SetFacetsProperty(const std::vector &raulInds, const std::vector &raulProps) const +void MeshAlgorithm::SetFacetsProperty(const std::vector& raulInds, + const std::vector& raulProps) const { - if (raulInds.size() != raulProps.size()) + if (raulInds.size() != raulProps.size()) { return; + } std::vector::const_iterator iP = raulProps.begin(); - for (std::vector::const_iterator i = raulInds.begin(); i != raulInds.end(); ++i, ++iP) + for (std::vector::const_iterator i = raulInds.begin(); i != raulInds.end(); + ++i, ++iP) { _rclMesh._aclFacetArray[*i].SetProperty(*iP); + } } -void MeshAlgorithm::SetFacetsFlag (const std::vector &raulInds, MeshFacet::TFlagType tF) const +void MeshAlgorithm::SetFacetsFlag(const std::vector& raulInds, + MeshFacet::TFlagType tF) const { - for (FacetIndex it : raulInds) + for (FacetIndex it : raulInds) { _rclMesh._aclFacetArray[it].SetFlag(tF); + } } -void MeshAlgorithm::SetPointsFlag (const std::vector &raulInds, MeshPoint::TFlagType tF) const +void MeshAlgorithm::SetPointsFlag(const std::vector& raulInds, + MeshPoint::TFlagType tF) const { - for (PointIndex it : raulInds) + for (PointIndex it : raulInds) { _rclMesh._aclPointArray[it].SetFlag(tF); + } } -void MeshAlgorithm::GetFacetsFlag (std::vector &raulInds, MeshFacet::TFlagType tF) const +void MeshAlgorithm::GetFacetsFlag(std::vector& raulInds, MeshFacet::TFlagType tF) const { raulInds.reserve(raulInds.size() + CountFacetFlag(tF)); MeshFacetArray::_TConstIterator beg = _rclMesh._aclFacetArray.begin(); MeshFacetArray::_TConstIterator end = _rclMesh._aclFacetArray.end(); for (MeshFacetArray::_TConstIterator it = beg; it != end; ++it) { - if (it->IsFlag(tF)) - raulInds.push_back(it-beg); + if (it->IsFlag(tF)) { + raulInds.push_back(it - beg); + } } } -void MeshAlgorithm::GetPointsFlag (std::vector &raulInds, MeshPoint::TFlagType tF) const +void MeshAlgorithm::GetPointsFlag(std::vector& raulInds, MeshPoint::TFlagType tF) const { raulInds.reserve(raulInds.size() + CountPointFlag(tF)); MeshPointArray::_TConstIterator beg = _rclMesh._aclPointArray.begin(); MeshPointArray::_TConstIterator end = _rclMesh._aclPointArray.end(); for (MeshPointArray::_TConstIterator it = beg; it != end; ++it) { - if (it->IsFlag(tF)) - raulInds.push_back(it-beg); + if (it->IsFlag(tF)) { + raulInds.push_back(it - beg); + } } } -void MeshAlgorithm::ResetFacetsFlag (const std::vector &raulInds, MeshFacet::TFlagType tF) const +void MeshAlgorithm::ResetFacetsFlag(const std::vector& raulInds, + MeshFacet::TFlagType tF) const { - for (FacetIndex it : raulInds) + for (FacetIndex it : raulInds) { _rclMesh._aclFacetArray[it].ResetFlag(tF); + } } -void MeshAlgorithm::ResetPointsFlag (const std::vector &raulInds, MeshPoint::TFlagType tF) const +void MeshAlgorithm::ResetPointsFlag(const std::vector& raulInds, + MeshPoint::TFlagType tF) const { - for (PointIndex it : raulInds) + for (PointIndex it : raulInds) { _rclMesh._aclPointArray[it].ResetFlag(tF); + } } -void MeshAlgorithm::SetFacetFlag (MeshFacet::TFlagType tF) const +void MeshAlgorithm::SetFacetFlag(MeshFacet::TFlagType tF) const { _rclMesh._aclFacetArray.SetFlag(tF); } -void MeshAlgorithm::SetPointFlag (MeshPoint::TFlagType tF) const +void MeshAlgorithm::SetPointFlag(MeshPoint::TFlagType tF) const { _rclMesh._aclPointArray.SetFlag(tF); } -void MeshAlgorithm::ResetFacetFlag (MeshFacet::TFlagType tF) const +void MeshAlgorithm::ResetFacetFlag(MeshFacet::TFlagType tF) const { _rclMesh._aclFacetArray.ResetFlag(tF); } -void MeshAlgorithm::ResetPointFlag (MeshPoint::TFlagType tF) const +void MeshAlgorithm::ResetPointFlag(MeshPoint::TFlagType tF) const { _rclMesh._aclPointArray.ResetFlag(tF); } -unsigned long MeshAlgorithm::CountFacetFlag (MeshFacet::TFlagType tF) const +unsigned long MeshAlgorithm::CountFacetFlag(MeshFacet::TFlagType tF) const { MeshIsFlag flag; - return std::count_if(_rclMesh._aclFacetArray.begin(), _rclMesh._aclFacetArray.end(), - [flag, tF](const MeshFacet& f) { return flag(f, tF);}); + return std::count_if(_rclMesh._aclFacetArray.begin(), + _rclMesh._aclFacetArray.end(), + [flag, tF](const MeshFacet& f) { + return flag(f, tF); + }); } -unsigned long MeshAlgorithm::CountPointFlag (MeshPoint::TFlagType tF) const +unsigned long MeshAlgorithm::CountPointFlag(MeshPoint::TFlagType tF) const { MeshIsFlag flag; - return std::count_if(_rclMesh._aclPointArray.begin(), _rclMesh._aclPointArray.end(), - [flag, tF](const MeshPoint& f) { return flag(f, tF);}); + return std::count_if(_rclMesh._aclPointArray.begin(), + _rclMesh._aclPointArray.end(), + [flag, tF](const MeshPoint& f) { + return flag(f, tF); + }); } -void MeshAlgorithm::GetFacetsFromToolMesh( const MeshKernel& rToolMesh, const Base::Vector3f& rcDir, std::vector &raclCutted ) const +void MeshAlgorithm::GetFacetsFromToolMesh(const MeshKernel& rToolMesh, + const Base::Vector3f& rcDir, + std::vector& raclCutted) const { MeshFacetIterator cFIt(_rclMesh); MeshFacetIterator cTIt(rToolMesh); @@ -899,24 +986,27 @@ void MeshAlgorithm::GetFacetsFromToolMesh( const MeshKernel& rToolMesh, const Ba // check each point of each facet for (const auto& pnt : cFIt->_aclPoints) { // at least the point must be inside the bounding box of the tool mesh - if (cBB.IsInBox( pnt)) { - // should not cause performance problems since the tool mesh is usually rather lightweight - int ct=0; + if (cBB.IsInBox(pnt)) { + // should not cause performance problems since the tool mesh is usually rather + // lightweight + int ct = 0; for (cTIt.Init(); cTIt.More(); cTIt.Next()) { - if (cTIt->IsPointOfFace( pnt, MeshPoint::epsilon())) { - ct=1; - break; // the point lies on the tool mesh + if (cTIt->IsPointOfFace(pnt, MeshPoint::epsilon())) { + ct = 1; + break; // the point lies on the tool mesh } - else if (cTIt->Foraminate( pnt, rcDir, tmp)) { - // check if the intersection point lies in direction rcDir of the considered point - if ((tmp - pnt) * rcDir > 0) + else if (cTIt->Foraminate(pnt, rcDir, tmp)) { + // check if the intersection point lies in direction rcDir of the considered + // point + if ((tmp - pnt) * rcDir > 0) { ct++; + } } } // odd number => point is inside the tool mesh if (ct % 2 == 1) { - raclCutted.push_back( cFIt.Position() ); + raclCutted.push_back(cFIt.Position()); break; } } @@ -926,8 +1016,10 @@ void MeshAlgorithm::GetFacetsFromToolMesh( const MeshKernel& rToolMesh, const Ba } } -void MeshAlgorithm::GetFacetsFromToolMesh(const MeshKernel& rToolMesh, const Base::Vector3f& rcDir, - const MeshFacetGrid& rGrid, std::vector &raclCutted) const +void MeshAlgorithm::GetFacetsFromToolMesh(const MeshKernel& rToolMesh, + const Base::Vector3f& rcDir, + const MeshFacetGrid& rGrid, + std::vector& raclCutted) const { // iterator over grid structure MeshGridIterator clGridIter(rGrid); @@ -983,17 +1075,20 @@ void MeshAlgorithm::GetFacetsFromToolMesh(const MeshKernel& rToolMesh, const Bas for (auto point : cFIt->_aclPoints) { // at least the point must be inside the bounding box of the tool mesh if (cBB.IsInBox(point)) { - // should not cause performance problems since the tool mesh is usually rather lightweight - int ct=0; + // should not cause performance problems since the tool mesh is usually rather + // lightweight + int ct = 0; for (cTIt.Init(); cTIt.More(); cTIt.Next()) { if (cTIt->IsPointOfFace(point, MeshPoint::epsilon())) { - ct=1; - break; // the point lies on the tool mesh + ct = 1; + break; // the point lies on the tool mesh } else if (cTIt->Foraminate(point, rcDir, tmp)) { - // check if the intersection point lies in direction rcDir of the considered point - if ((tmp - point) * rcDir > 0) + // check if the intersection point lies in direction rcDir of the considered + // point + if ((tmp - point) * rcDir > 0) { ct++; + } } } @@ -1021,60 +1116,60 @@ int MeshAlgorithm::Surround(const Base::BoundBox3f& rBox, const Base::Vector3f& // at least both boxes intersect if (cBB && rBox) { // check for intersections with the actual mesh - Base::Vector3f cCorner[8] = { - Base::Vector3f(rBox.MinX,rBox.MinY,rBox.MinZ), Base::Vector3f(rBox.MaxX,rBox.MinY,rBox.MinZ), - Base::Vector3f(rBox.MaxX,rBox.MaxY,rBox.MinZ), Base::Vector3f(rBox.MinX,rBox.MaxY,rBox.MinZ), - Base::Vector3f(rBox.MinX,rBox.MinY,rBox.MaxZ), Base::Vector3f(rBox.MaxX,rBox.MinY,rBox.MaxZ), - Base::Vector3f(rBox.MaxX,rBox.MaxY,rBox.MaxZ), Base::Vector3f(rBox.MinX,rBox.MaxY,rBox.MaxZ)}; + Base::Vector3f cCorner[8] = {Base::Vector3f(rBox.MinX, rBox.MinY, rBox.MinZ), + Base::Vector3f(rBox.MaxX, rBox.MinY, rBox.MinZ), + Base::Vector3f(rBox.MaxX, rBox.MaxY, rBox.MinZ), + Base::Vector3f(rBox.MinX, rBox.MaxY, rBox.MinZ), + Base::Vector3f(rBox.MinX, rBox.MinY, rBox.MaxZ), + Base::Vector3f(rBox.MaxX, rBox.MinY, rBox.MaxZ), + Base::Vector3f(rBox.MaxX, rBox.MaxY, rBox.MaxZ), + Base::Vector3f(rBox.MinX, rBox.MaxY, rBox.MaxZ)}; MeshFacetIterator cTIt(_rclMesh); // triangulation of the box - int triangles[36] = { - 0,1,2,0,2,3, - 0,1,5,0,5,4, - 0,4,7,0,7,3, - 6,7,4,6,4,5, - 6,2,3,6,3,7, - 6,1,2,6,5,1 - }; + int triangles[36] = {0, 1, 2, 0, 2, 3, 0, 1, 5, 0, 5, 4, 0, 4, 7, 0, 7, 3, + 6, 7, 4, 6, 4, 5, 6, 2, 3, 6, 3, 7, 6, 1, 2, 6, 5, 1}; std::vector cFacet(12); - int id=0; - for (size_t ii=0; ii<12; ii++) { - cFacet[ii]._aclPoints[0]=cCorner[triangles[id++]]; - cFacet[ii]._aclPoints[1]=cCorner[triangles[id++]]; - cFacet[ii]._aclPoints[2]=cCorner[triangles[id++]]; + int id = 0; + for (size_t ii = 0; ii < 12; ii++) { + cFacet[ii]._aclPoints[0] = cCorner[triangles[id++]]; + cFacet[ii]._aclPoints[1] = cCorner[triangles[id++]]; + cFacet[ii]._aclPoints[2] = cCorner[triangles[id++]]; } // check for intersections of the box with the mesh - for (const auto & it : cFacet) { + for (const auto& it : cFacet) { for (cTIt.Init(); cTIt.More(); cTIt.Next()) { - int ret = cTIt->IntersectWithFacet(it,pt1, pt2); + int ret = cTIt->IntersectWithFacet(it, pt1, pt2); // the box intersects the mesh? - if (ret != 0) - return 0; // => no more investigations required + if (ret != 0) { + return 0; // => no more investigations required + } } } // Now we know that the box doesn't intersect with the mesh. This means that either the box // is completely inside or outside the mesh. To check this we test one point of the box // whether it is inside or outside. - int ct=0; + int ct = 0; for (cTIt.Init(); cTIt.More(); cTIt.Next()) { if (cTIt->IsPointOfFace(cCorner[0], MeshPoint::epsilon())) { - ct=1; - break; // the point lies on the tool mesh + ct = 1; + break; // the point lies on the tool mesh } else if (cTIt->Foraminate(cCorner[0], rcDir, tmp)) { // check if the intersection point lies in direction rcDir of the considered point - if ((tmp - cCorner[0]) * rcDir > 0) + if ((tmp - cCorner[0]) * rcDir > 0) { ct++; + } } } - // odd number => point (i.e. the box) is inside the mesh, even number => point is outside the mesh + // odd number => point (i.e. the box) is inside the mesh, even number => point is outside + // the mesh return (ct % 2 == 1) ? 1 : -1; } @@ -1082,8 +1177,11 @@ int MeshAlgorithm::Surround(const Base::BoundBox3f& rBox, const Base::Vector3f& return -1; } -void MeshAlgorithm::CheckFacets(const MeshFacetGrid& rclGrid, const Base::ViewProjMethod* pclProj, const Base::Polygon2d& rclPoly, - bool bInner, std::vector &raulFacets) const +void MeshAlgorithm::CheckFacets(const MeshFacetGrid& rclGrid, + const Base::ViewProjMethod* pclProj, + const Base::Polygon2d& rclPoly, + bool bInner, + std::vector& raulFacets) const { std::vector::iterator it; MeshFacetIterator clIter(_rclMesh, 0); @@ -1113,7 +1211,8 @@ void MeshAlgorithm::CheckFacets(const MeshFacetGrid& rclGrid, const Base::ViewPr // remove duplicates std::sort(aulAllElements.begin(), aulAllElements.end()); - aulAllElements.erase(std::unique(aulAllElements.begin(), aulAllElements.end()), aulAllElements.end()); + aulAllElements.erase(std::unique(aulAllElements.begin(), aulAllElements.end()), + aulAllElements.end()); Base::SequencerLauncher seq("Check facets", aulAllElements.size()); @@ -1121,11 +1220,11 @@ void MeshAlgorithm::CheckFacets(const MeshFacetGrid& rclGrid, const Base::ViewPr bNoPointInside = true; clGravityOfFacet.Set(0.0f, 0.0f, 0.0f); MeshGeomFacet rclFacet = _rclMesh.GetFacet(*it); - for (const auto & pnt : rclFacet._aclPoints) { + for (const auto& pnt : rclFacet._aclPoints) { clPt2d = fixedProj(pnt); clGravityOfFacet += clPt2d; - if (clPolyBBox.Contains(Base::Vector2d(clPt2d.x, clPt2d.y)) && - rclPoly.Contains(Base::Vector2d(clPt2d.x, clPt2d.y))) { + if (clPolyBBox.Contains(Base::Vector2d(clPt2d.x, clPt2d.y)) + && rclPoly.Contains(Base::Vector2d(clPt2d.x, clPt2d.y))) { raulFacets.push_back(*it); bNoPointInside = false; break; @@ -1134,11 +1233,12 @@ void MeshAlgorithm::CheckFacets(const MeshFacetGrid& rclGrid, const Base::ViewPr // if no facet point is inside the polygon then check also the gravity if (bNoPointInside) { - clGravityOfFacet *= 1.0f/3.0f; + clGravityOfFacet *= 1.0f / 3.0f; - if (clPolyBBox.Contains(Base::Vector2d(clGravityOfFacet.x, clGravityOfFacet.y)) && - rclPoly.Contains(Base::Vector2d(clGravityOfFacet.x, clGravityOfFacet.y))) + if (clPolyBBox.Contains(Base::Vector2d(clGravityOfFacet.x, clGravityOfFacet.y)) + && rclPoly.Contains(Base::Vector2d(clGravityOfFacet.x, clGravityOfFacet.y))) { raulFacets.push_back(*it); + } } seq.next(); @@ -1150,8 +1250,8 @@ void MeshAlgorithm::CheckFacets(const MeshFacetGrid& rclGrid, const Base::ViewPr for (clIter.Init(); clIter.More(); clIter.Next()) { for (const auto& pnt : clIter->_aclPoints) { clPt2d = fixedProj(pnt); - if ((clPolyBBox.Contains(Base::Vector2d(clPt2d.x, clPt2d.y)) && - !rclPoly.Contains(Base::Vector2d(clPt2d.x, clPt2d.y)))) { + if ((clPolyBBox.Contains(Base::Vector2d(clPt2d.x, clPt2d.y)) + && !rclPoly.Contains(Base::Vector2d(clPt2d.x, clPt2d.y)))) { raulFacets.push_back(clIter.Position()); break; } @@ -1161,8 +1261,10 @@ void MeshAlgorithm::CheckFacets(const MeshFacetGrid& rclGrid, const Base::ViewPr } } -void MeshAlgorithm::CheckFacets(const Base::ViewProjMethod* pclProj, const Base::Polygon2d& rclPoly, - bool bInner, std::vector &raulFacets) const +void MeshAlgorithm::CheckFacets(const Base::ViewProjMethod* pclProj, + const Base::Polygon2d& rclPoly, + bool bInner, + std::vector& raulFacets) const { const MeshPointArray& p = _rclMesh.GetPoints(); const MeshFacetArray& f = _rclMesh.GetFacets(); @@ -1172,14 +1274,15 @@ void MeshAlgorithm::CheckFacets(const Base::ViewProjMethod* pclProj, const Base: // Precompute the screen projection matrix as Coin's projection function is expensive Base::ViewProjMatrix fixedProj(pclProj->getComposedProjectionMatrix()); - FacetIndex index=0; - for (MeshFacetArray::_TConstIterator it = f.begin(); it != f.end(); ++it,++index) { + FacetIndex index = 0; + for (MeshFacetArray::_TConstIterator it = f.begin(); it != f.end(); ++it, ++index) { for (PointIndex ptIndex : it->_aulPoints) { pt2d = fixedProj(p[ptIndex]); // First check whether the point is in the bounding box of the polygon - if ((bb.Contains(Base::Vector2d(pt2d.x, pt2d.y)) && - rclPoly.Contains(Base::Vector2d(pt2d.x, pt2d.y))) ^ !bInner) { + if ((bb.Contains(Base::Vector2d(pt2d.x, pt2d.y)) + && rclPoly.Contains(Base::Vector2d(pt2d.x, pt2d.y))) + ^ !bInner) { raulFacets.push_back(index); break; } @@ -1187,30 +1290,32 @@ void MeshAlgorithm::CheckFacets(const Base::ViewProjMethod* pclProj, const Base: } } -float MeshAlgorithm::Surface () const +float MeshAlgorithm::Surface() const { - float fTotal = 0.0f; + float fTotal = 0.0f; MeshFacetIterator clFIter(_rclMesh); - for (clFIter.Init(); clFIter.More(); clFIter.Next()) - fTotal += clFIter->Area(); + for (clFIter.Init(); clFIter.More(); clFIter.Next()) { + fTotal += clFIter->Area(); + } return fTotal; } -void MeshAlgorithm::SubSampleByDist (float fDist, std::vector &rclPoints) const +void MeshAlgorithm::SubSampleByDist(float fDist, std::vector& rclPoints) const { rclPoints.clear(); MeshFacetIterator clFIter(_rclMesh); for (clFIter.Init(); clFIter.More(); clFIter.Next()) { size_t k = rclPoints.size(); clFIter->SubSample(fDist, rclPoints); - if (rclPoints.size() == k) - rclPoints.push_back(clFIter->GetGravityPoint()); // min. add middle point + if (rclPoints.size() == k) { + rclPoints.push_back(clFIter->GetGravityPoint()); // min. add middle point + } } } -void MeshAlgorithm::SubSampleAllPoints (std::vector &rclPoints) const +void MeshAlgorithm::SubSampleAllPoints(std::vector& rclPoints) const { rclPoints.clear(); @@ -1222,245 +1327,260 @@ void MeshAlgorithm::SubSampleAllPoints (std::vector &rclPoints) } } -void MeshAlgorithm::SubSampleByCount (unsigned long ulCtPoints, std::vector &rclPoints) const +void MeshAlgorithm::SubSampleByCount(unsigned long ulCtPoints, + std::vector& rclPoints) const { float fDist = float(sqrt(Surface() / float(ulCtPoints))); SubSampleByDist(fDist, rclPoints); } -void MeshAlgorithm::SearchFacetsFromPolyline (const std::vector &rclPolyline, float fRadius, - const MeshFacetGrid& rclGrid, std::vector &rclResultFacetsIndices) const +void MeshAlgorithm::SearchFacetsFromPolyline(const std::vector& rclPolyline, + float fRadius, + const MeshFacetGrid& rclGrid, + std::vector& rclResultFacetsIndices) const { - rclResultFacetsIndices.clear(); - if ( rclPolyline.size() < 3 ) - return; // no polygon defined - - std::set aclFacets; - for (std::vector::const_iterator pV = rclPolyline.begin(); pV < (rclPolyline.end() - 1); ++pV) - { - const Base::Vector3f &rclP0 = *pV, &rclP1 = *(pV + 1); - - // BB eines Polyline-Segments - BoundBox3f clSegmBB(rclP0.x, rclP0.y, rclP0.z, rclP0.x, rclP0.y, rclP0.z); - clSegmBB.Add(rclP1); - clSegmBB.Enlarge(fRadius); // BB um Suchradius vergroessern - - std::vector aclBBFacets; - unsigned long k = rclGrid.Inside(clSegmBB, aclBBFacets, false); - for (unsigned long i = 0; i < k; i++) - { - if (_rclMesh.GetFacet(aclBBFacets[i]).DistanceToLineSegment(rclP0, rclP1) < fRadius) - aclFacets.insert(aclBBFacets[i]); + rclResultFacetsIndices.clear(); + if (rclPolyline.size() < 3) { + return; // no polygon defined } - } - rclResultFacetsIndices.insert(rclResultFacetsIndices.begin(), aclFacets.begin(), aclFacets.end()); + std::set aclFacets; + for (std::vector::const_iterator pV = rclPolyline.begin(); + pV < (rclPolyline.end() - 1); + ++pV) { + const Base::Vector3f &rclP0 = *pV, &rclP1 = *(pV + 1); + + // BB eines Polyline-Segments + BoundBox3f clSegmBB(rclP0.x, rclP0.y, rclP0.z, rclP0.x, rclP0.y, rclP0.z); + clSegmBB.Add(rclP1); + clSegmBB.Enlarge(fRadius); // BB um Suchradius vergroessern + + std::vector aclBBFacets; + unsigned long k = rclGrid.Inside(clSegmBB, aclBBFacets, false); + for (unsigned long i = 0; i < k; i++) { + if (_rclMesh.GetFacet(aclBBFacets[i]).DistanceToLineSegment(rclP0, rclP1) < fRadius) { + aclFacets.insert(aclBBFacets[i]); + } + } + } + + rclResultFacetsIndices.insert(rclResultFacetsIndices.begin(), + aclFacets.begin(), + aclFacets.end()); } -void MeshAlgorithm::CutBorderFacets (std::vector &raclFacetIndices, unsigned short usLevel) const +void MeshAlgorithm::CutBorderFacets(std::vector& raclFacetIndices, + unsigned short usLevel) const { - std::vector aclToDelete; + std::vector aclToDelete; - CheckBorderFacets(raclFacetIndices, aclToDelete, usLevel); + CheckBorderFacets(raclFacetIndices, aclToDelete, usLevel); - // alle gefunden "Rand"-Facetsindizes" aus dem Array loeschen - std::vector aclResult; - std::set aclTmp(aclToDelete.begin(), aclToDelete.end()); + // alle gefunden "Rand"-Facetsindizes" aus dem Array loeschen + std::vector aclResult; + std::set aclTmp(aclToDelete.begin(), aclToDelete.end()); - for (FacetIndex facetIndex : raclFacetIndices) - { - if (aclTmp.find(facetIndex) == aclTmp.end()) - aclResult.push_back(facetIndex); - } + for (FacetIndex facetIndex : raclFacetIndices) { + if (aclTmp.find(facetIndex) == aclTmp.end()) { + aclResult.push_back(facetIndex); + } + } - raclFacetIndices = aclResult; + raclFacetIndices = aclResult; } unsigned long MeshAlgorithm::CountBorderEdges() const { - unsigned long cnt=0; - const MeshFacetArray &rclFAry = _rclMesh._aclFacetArray; + unsigned long cnt = 0; + const MeshFacetArray& rclFAry = _rclMesh._aclFacetArray; MeshFacetArray::_TConstIterator end = rclFAry.end(); for (MeshFacetArray::_TConstIterator it = rclFAry.begin(); it != end; ++it) { for (FacetIndex facetIndex : it->_aulNeighbours) { - if (facetIndex == FACET_INDEX_MAX) + if (facetIndex == FACET_INDEX_MAX) { cnt++; + } } } return cnt; } -void MeshAlgorithm::CheckBorderFacets (const std::vector &raclFacetIndices, std::vector &raclResultIndices, unsigned short usLevel) const +void MeshAlgorithm::CheckBorderFacets(const std::vector& raclFacetIndices, + std::vector& raclResultIndices, + unsigned short usLevel) const { - ResetFacetFlag(MeshFacet::TMP0); - SetFacetsFlag(raclFacetIndices, MeshFacet::TMP0); + ResetFacetFlag(MeshFacet::TMP0); + SetFacetsFlag(raclFacetIndices, MeshFacet::TMP0); - const MeshFacetArray &rclFAry = _rclMesh._aclFacetArray; + const MeshFacetArray& rclFAry = _rclMesh._aclFacetArray; - for (unsigned short usL = 0; usL < usLevel; usL++) - { - for (FacetIndex facetIndex : raclFacetIndices) - { - for (FacetIndex ulNB : rclFAry[facetIndex]._aulNeighbours) - { - if (ulNB == FACET_INDEX_MAX) - { - raclResultIndices.push_back(facetIndex); - rclFAry[facetIndex].ResetFlag(MeshFacet::TMP0); - continue; + for (unsigned short usL = 0; usL < usLevel; usL++) { + for (FacetIndex facetIndex : raclFacetIndices) { + for (FacetIndex ulNB : rclFAry[facetIndex]._aulNeighbours) { + if (ulNB == FACET_INDEX_MAX) { + raclResultIndices.push_back(facetIndex); + rclFAry[facetIndex].ResetFlag(MeshFacet::TMP0); + continue; + } + if (!rclFAry[ulNB].IsFlag(MeshFacet::TMP0)) { + raclResultIndices.push_back(facetIndex); + rclFAry[facetIndex].ResetFlag(MeshFacet::TMP0); + continue; + } + } } - if (!rclFAry[ulNB].IsFlag(MeshFacet::TMP0)) - { - raclResultIndices.push_back(facetIndex); - rclFAry[facetIndex].ResetFlag(MeshFacet::TMP0); - continue; + } +} + +void MeshAlgorithm::GetBorderPoints(const std::vector& raclFacetIndices, + std::set& raclResultPointsIndices) const +{ + ResetFacetFlag(MeshFacet::TMP0); + SetFacetsFlag(raclFacetIndices, MeshFacet::TMP0); + + const MeshFacetArray& rclFAry = _rclMesh._aclFacetArray; + + for (FacetIndex facetIndex : raclFacetIndices) { + for (int i = 0; i < 3; i++) { + const MeshFacet& rclFacet = rclFAry[facetIndex]; + FacetIndex ulNB = rclFacet._aulNeighbours[i]; + if (ulNB == FACET_INDEX_MAX) { + raclResultPointsIndices.insert(rclFacet._aulPoints[i]); + raclResultPointsIndices.insert(rclFacet._aulPoints[(i + 1) % 3]); + continue; + } + if (!rclFAry[ulNB].IsFlag(MeshFacet::TMP0)) { + raclResultPointsIndices.insert(rclFacet._aulPoints[i]); + raclResultPointsIndices.insert(rclFacet._aulPoints[(i + 1) % 3]); + continue; + } } - } } - } } -void MeshAlgorithm::GetBorderPoints (const std::vector &raclFacetIndices, std::set &raclResultPointsIndices) const +bool MeshAlgorithm::NearestPointFromPoint(const Base::Vector3f& rclPt, + FacetIndex& rclResFacetIndex, + Base::Vector3f& rclResPoint) const { - ResetFacetFlag(MeshFacet::TMP0); - SetFacetsFlag(raclFacetIndices, MeshFacet::TMP0); - - const MeshFacetArray &rclFAry = _rclMesh._aclFacetArray; - - for (FacetIndex facetIndex : raclFacetIndices) - { - for (int i = 0; i < 3; i++) - { - const MeshFacet &rclFacet = rclFAry[facetIndex]; - FacetIndex ulNB = rclFacet._aulNeighbours[i]; - if (ulNB == FACET_INDEX_MAX) - { - raclResultPointsIndices.insert(rclFacet._aulPoints[i]); - raclResultPointsIndices.insert(rclFacet._aulPoints[(i+1)%3]); - continue; - } - if (!rclFAry[ulNB].IsFlag(MeshFacet::TMP0)) - { - raclResultPointsIndices.insert(rclFacet._aulPoints[i]); - raclResultPointsIndices.insert(rclFacet._aulPoints[(i+1)%3]); - continue; - } + if (_rclMesh.CountFacets() == 0) { + return false; } - } -} -bool MeshAlgorithm::NearestPointFromPoint (const Base::Vector3f &rclPt, FacetIndex &rclResFacetIndex, Base::Vector3f &rclResPoint) const -{ - if (_rclMesh.CountFacets() == 0) - return false; - - // calc each facet - float fMinDist = FLOAT_MAX; - FacetIndex ulInd = FACET_INDEX_MAX; - MeshFacetIterator pF(_rclMesh); - for (pF.Init(); pF.More(); pF.Next()) - { - float fDist = pF->DistanceToPoint(rclPt); - if (fDist < fMinDist) - { - fMinDist = fDist; - ulInd = pF.Position(); + // calc each facet + float fMinDist = FLOAT_MAX; + FacetIndex ulInd = FACET_INDEX_MAX; + MeshFacetIterator pF(_rclMesh); + for (pF.Init(); pF.More(); pF.Next()) { + float fDist = pF->DistanceToPoint(rclPt); + if (fDist < fMinDist) { + fMinDist = fDist; + ulInd = pF.Position(); + } } - } - MeshGeomFacet rclSFacet = _rclMesh.GetFacet(ulInd); - rclSFacet.DistanceToPoint(rclPt, rclResPoint); - rclResFacetIndex = ulInd; + MeshGeomFacet rclSFacet = _rclMesh.GetFacet(ulInd); + rclSFacet.DistanceToPoint(rclPt, rclResPoint); + rclResFacetIndex = ulInd; - return true; + return true; } -bool MeshAlgorithm::NearestPointFromPoint (const Base::Vector3f &rclPt, const MeshFacetGrid& rclGrid, FacetIndex &rclResFacetIndex, Base::Vector3f &rclResPoint) const +bool MeshAlgorithm::NearestPointFromPoint(const Base::Vector3f& rclPt, + const MeshFacetGrid& rclGrid, + FacetIndex& rclResFacetIndex, + Base::Vector3f& rclResPoint) const { - FacetIndex ulInd = rclGrid.SearchNearestFromPoint(rclPt); + FacetIndex ulInd = rclGrid.SearchNearestFromPoint(rclPt); - if (ulInd == FACET_INDEX_MAX) - { - return false; - } + if (ulInd == FACET_INDEX_MAX) { + return false; + } - MeshGeomFacet rclSFacet = _rclMesh.GetFacet(ulInd); - rclSFacet.DistanceToPoint(rclPt, rclResPoint); - rclResFacetIndex = ulInd; + MeshGeomFacet rclSFacet = _rclMesh.GetFacet(ulInd); + rclSFacet.DistanceToPoint(rclPt, rclResPoint); + rclResFacetIndex = ulInd; - return true; + return true; } -bool MeshAlgorithm::NearestPointFromPoint (const Base::Vector3f &rclPt, const MeshFacetGrid& rclGrid, float fMaxSearchArea, - FacetIndex &rclResFacetIndex, Base::Vector3f &rclResPoint) const +bool MeshAlgorithm::NearestPointFromPoint(const Base::Vector3f& rclPt, + const MeshFacetGrid& rclGrid, + float fMaxSearchArea, + FacetIndex& rclResFacetIndex, + Base::Vector3f& rclResPoint) const { - FacetIndex ulInd = rclGrid.SearchNearestFromPoint(rclPt, fMaxSearchArea); + FacetIndex ulInd = rclGrid.SearchNearestFromPoint(rclPt, fMaxSearchArea); - if (ulInd == FACET_INDEX_MAX) - return false; // no facets inside BoundingBox + if (ulInd == FACET_INDEX_MAX) { + return false; // no facets inside BoundingBox + } - MeshGeomFacet rclSFacet = _rclMesh.GetFacet(ulInd); - rclSFacet.DistanceToPoint(rclPt, rclResPoint); - rclResFacetIndex = ulInd; + MeshGeomFacet rclSFacet = _rclMesh.GetFacet(ulInd); + rclSFacet.DistanceToPoint(rclPt, rclResPoint); + rclResFacetIndex = ulInd; - return true; + return true; } -bool MeshAlgorithm::CutWithPlane (const Base::Vector3f &clBase, const Base::Vector3f &clNormal, const MeshFacetGrid &rclGrid, - std::list > &rclResult, float fMinEps, bool bConnectPolygons) const +bool MeshAlgorithm::CutWithPlane(const Base::Vector3f& clBase, + const Base::Vector3f& clNormal, + const MeshFacetGrid& rclGrid, + std::list>& rclResult, + float fMinEps, + bool bConnectPolygons) const { - std::vector aulFacets; + std::vector aulFacets; - // Search grid - MeshGridIterator clGridIter(rclGrid); - for (clGridIter.Init(); clGridIter.More(); clGridIter.Next()) - { - // if Gridvoxel intersects the plane: pick up all facets for cutting - if (clGridIter.GetBoundBox().IsCutPlane(clBase, clNormal)) - clGridIter.GetElements(aulFacets); - } + // Search grid + MeshGridIterator clGridIter(rclGrid); + for (clGridIter.Init(); clGridIter.More(); clGridIter.Next()) { + // if Gridvoxel intersects the plane: pick up all facets for cutting + if (clGridIter.GetBoundBox().IsCutPlane(clBase, clNormal)) { + clGridIter.GetElements(aulFacets); + } + } - // remove multiple triangles - std::sort(aulFacets.begin(), aulFacets.end()); - aulFacets.erase(std::unique(aulFacets.begin(), aulFacets.end()), aulFacets.end()); + // remove multiple triangles + std::sort(aulFacets.begin(), aulFacets.end()); + aulFacets.erase(std::unique(aulFacets.begin(), aulFacets.end()), aulFacets.end()); - // intersect all facets with plane - std::list > clTempPoly; // Field with intersection lines (unsorted, not chained) + // intersect all facets with plane + std::list> + clTempPoly; // Field with intersection lines (unsorted, not chained) - for (FacetIndex facetIndex : aulFacets) - { - Base::Vector3f clE1, clE2; - const MeshGeomFacet clF(_rclMesh.GetFacet(facetIndex)); + for (FacetIndex facetIndex : aulFacets) { + Base::Vector3f clE1, clE2; + const MeshGeomFacet clF(_rclMesh.GetFacet(facetIndex)); - // Cut the facet and store the cutting path - if (clF.IntersectWithPlane(clBase, clNormal, clE1, clE2)) - clTempPoly.emplace_back(clE1, clE2); - } + // Cut the facet and store the cutting path + if (clF.IntersectWithPlane(clBase, clNormal, clE1, clE2)) { + clTempPoly.emplace_back(clE1, clE2); + } + } - if(bConnectPolygons) - { - //std::list > rclTempLines; - std::list > rclResultLines(clTempPoly.begin(),clTempPoly.end()); - std::list > tempList; - ConnectLines(clTempPoly, tempList, fMinEps); - ConnectPolygons(tempList, clTempPoly); + if (bConnectPolygons) { + // std::list > rclTempLines; + std::list> rclResultLines(clTempPoly.begin(), + clTempPoly.end()); + std::list> tempList; + ConnectLines(clTempPoly, tempList, fMinEps); + ConnectPolygons(tempList, clTempPoly); - for(auto & iter : clTempPoly) - { - rclResultLines.push_front(iter); - } + for (auto& iter : clTempPoly) { + rclResultLines.push_front(iter); + } - return ConnectLines(rclResultLines, rclResult, fMinEps); - } + return ConnectLines(rclResultLines, rclResult, fMinEps); + } - return ConnectLines(clTempPoly, rclResult, fMinEps); + return ConnectLines(clTempPoly, rclResult, fMinEps); } -bool MeshAlgorithm::ConnectLines (std::list > &rclLines, - std::list > &rclPolylines, float fMinEps) const +bool MeshAlgorithm::ConnectLines(std::list>& rclLines, + std::list>& rclPolylines, + float fMinEps) const { - using TCIter = std::list >::iterator; + using TCIter = std::list>::iterator; // square search radius // const float fMinEps = 1.0e-2f; // := 10 micrometer distance @@ -1470,12 +1590,14 @@ bool MeshAlgorithm::ConnectLines (std::list _clToDelete; float fToDelDist = fMinEps / 10.0f; for (TCIter pF = rclLines.begin(); pF != rclLines.end(); ++pF) { - if (Base::DistanceP2(pF->first, pF->second) < fToDelDist) - _clToDelete.push_back(pF); + if (Base::DistanceP2(pF->first, pF->second) < fToDelDist) { + _clToDelete.push_back(pF); + } } - for (auto & pI : _clToDelete) + for (auto& pI : _clToDelete) { rclLines.erase(pI); + } while (!rclLines.empty()) { TCIter pF; @@ -1485,7 +1607,7 @@ bool MeshAlgorithm::ConnectLines (std::listfirst; // current start point of the polyline - Base::Vector3f clEnd = rclLines.begin()->second; // current end point of the polyline + Base::Vector3f clEnd = rclLines.begin()->second; // current end point of the polyline clPoly.push_back(clFront); clPoly.push_back(clEnd); rclLines.erase(rclLines.begin()); @@ -1494,33 +1616,33 @@ bool MeshAlgorithm::ConnectLines (std::listfirst) < fFrontMin) { - fFrontMin = Base::DistanceP2(clFront, pF->first); - pFront = pF; + fFrontMin = Base::DistanceP2(clFront, pF->first); + pFront = pF; bFrontFirst = true; } else if (Base::DistanceP2(clEnd, pF->first) < fEndMin) { - fEndMin = Base::DistanceP2(clEnd, pF->first); - pEnd = pF; - bEndFirst = true; + fEndMin = Base::DistanceP2(clEnd, pF->first); + pEnd = pF; + bEndFirst = true; } else if (Base::DistanceP2(clFront, pF->second) < fFrontMin) { - fFrontMin = Base::DistanceP2(clFront, pF->second); - pFront = pF; + fFrontMin = Base::DistanceP2(clFront, pF->second); + pFront = pF; bFrontFirst = false; } else if (Base::DistanceP2(clEnd, pF->second) < fEndMin) { - fEndMin = Base::DistanceP2(clEnd, pF->second); - pEnd = pF; - bEndFirst = false; + fEndMin = Base::DistanceP2(clEnd, pF->second); + pEnd = pF; + bEndFirst = false; } } @@ -1551,64 +1673,75 @@ bool MeshAlgorithm::ConnectLines (std::list >::iterator; + using TPIter = std::list>::iterator; std::list _clPolyToDelete; for (TPIter pJ = rclPolylines.begin(); pJ != rclPolylines.end(); ++pJ) { - if (pJ->size() == 2) { // only one line segment - if (Base::DistanceP2(*pJ->begin(), *(pJ->begin() + 1)) <= fMinEps) + if (pJ->size() == 2) { // only one line segment + if (Base::DistanceP2(*pJ->begin(), *(pJ->begin() + 1)) <= fMinEps) { _clPolyToDelete.push_back(pJ); + } } } - for (auto & pK : _clPolyToDelete) + for (auto& pK : _clPolyToDelete) { rclPolylines.erase(pK); + } return true; } -bool MeshAlgorithm::ConnectPolygons(std::list > &clPolyList, - std::list > &rclLines) const +bool MeshAlgorithm::ConnectPolygons( + std::list>& clPolyList, + std::list>& rclLines) const { - for (std::list< std::vector >::iterator OutIter = clPolyList.begin(); OutIter != clPolyList.end(); ++OutIter) { - if (OutIter->empty()) + for (std::list>::iterator OutIter = clPolyList.begin(); + OutIter != clPolyList.end(); + ++OutIter) { + if (OutIter->empty()) { continue; - std::pair currentSort; - float fDist = Base::Distance(OutIter->front(),OutIter->back()); + } + std::pair currentSort; + float fDist = Base::Distance(OutIter->front(), OutIter->back()); currentSort.first = OutIter->front(); currentSort.second = OutIter->back(); - for (std::list< std::vector >::iterator InnerIter = clPolyList.begin(); InnerIter != clPolyList.end(); ++InnerIter) { - if (OutIter == InnerIter) + for (std::list>::iterator InnerIter = clPolyList.begin(); + InnerIter != clPolyList.end(); + ++InnerIter) { + if (OutIter == InnerIter) { continue; + } if (Base::Distance(OutIter->front(), InnerIter->front()) < fDist) { currentSort.second = InnerIter->front(); - fDist = Base::Distance(OutIter->front(),InnerIter->front()); + fDist = Base::Distance(OutIter->front(), InnerIter->front()); } if (Base::Distance(OutIter->front(), InnerIter->back()) < fDist) { currentSort.second = InnerIter->back(); - fDist = Base::Distance(OutIter->front(),InnerIter->back()); + fDist = Base::Distance(OutIter->front(), InnerIter->back()); } } rclLines.push_front(currentSort); - } return true; } -void MeshAlgorithm::GetFacetsFromPlane (const MeshFacetGrid &rclGrid, const Base::Vector3f& clNormal, float d, const Base::Vector3f &rclLeft, - const Base::Vector3f &rclRight, std::vector &rclRes) const +void MeshAlgorithm::GetFacetsFromPlane(const MeshFacetGrid& rclGrid, + const Base::Vector3f& clNormal, + float d, + const Base::Vector3f& rclLeft, + const Base::Vector3f& rclRight, + std::vector& rclRes) const { std::vector aulFacets; @@ -1621,8 +1754,9 @@ void MeshAlgorithm::GetFacetsFromPlane (const MeshFacetGrid &rclGrid, const Base MeshGridIterator clGridIter(rclGrid); for (clGridIter.Init(); clGridIter.More(); clGridIter.Next()) { // add facets from grid if the plane if cut the grid-voxel - if (clGridIter.GetBoundBox().IsCutPlane(clBase, clNormal)) + if (clGridIter.GetBoundBox().IsCutPlane(clBase, clNormal)) { clGridIter.GetElements(aulFacets); + } } // testing facet against planes @@ -1632,67 +1766,79 @@ void MeshAlgorithm::GetFacetsFromPlane (const MeshFacetGrid &rclGrid, const Base bool bInner = false; for (int i = 0; (i < 3) && !bInner; i++) { Base::Vector3f clPt = clSFacet._aclPoints[i]; - if ((clPt.DistanceToPlane(rclLeft, clPtNormal) <= 0.0f) && (clPt.DistanceToPlane(rclRight, clPtNormal) >= 0.0f)) + if ((clPt.DistanceToPlane(rclLeft, clPtNormal) <= 0.0f) + && (clPt.DistanceToPlane(rclRight, clPtNormal) >= 0.0f)) { bInner = true; + } } - if (bInner) + if (bInner) { rclRes.push_back(facetIndex); + } } } } -void MeshAlgorithm::PointsFromFacetsIndices (const std::vector &rvecIndices, std::vector &rvecPoints) const +void MeshAlgorithm::PointsFromFacetsIndices(const std::vector& rvecIndices, + std::vector& rvecPoints) const { - const MeshFacetArray &rclFAry = _rclMesh._aclFacetArray; - const MeshPointArray &rclPAry = _rclMesh._aclPointArray; + const MeshFacetArray& rclFAry = _rclMesh._aclFacetArray; + const MeshPointArray& rclPAry = _rclMesh._aclPointArray; - std::set setPoints; + std::set setPoints; - for (FacetIndex facetIndex : rvecIndices) - { - for (PointIndex pointIndex : rclFAry[facetIndex]._aulPoints) - setPoints.insert(pointIndex); - } + for (FacetIndex facetIndex : rvecIndices) { + for (PointIndex pointIndex : rclFAry[facetIndex]._aulPoints) { + setPoints.insert(pointIndex); + } + } - rvecPoints.clear(); - for (PointIndex pointIndex : setPoints) - rvecPoints.push_back(rclPAry[pointIndex]); + rvecPoints.clear(); + for (PointIndex pointIndex : setPoints) { + rvecPoints.push_back(rclPAry[pointIndex]); + } } -bool MeshAlgorithm::Distance (const Base::Vector3f &rclPt, FacetIndex ulFacetIdx, float fMaxDistance, float &rfDistance) const +bool MeshAlgorithm::Distance(const Base::Vector3f& rclPt, + FacetIndex ulFacetIdx, + float fMaxDistance, + float& rfDistance) const { - const MeshFacetArray &rclFAry = _rclMesh._aclFacetArray; - const MeshPointArray &rclPAry = _rclMesh._aclPointArray; - const PointIndex *pulIdx = rclFAry[ulFacetIdx]._aulPoints; + const MeshFacetArray& rclFAry = _rclMesh._aclFacetArray; + const MeshPointArray& rclPAry = _rclMesh._aclPointArray; + const PointIndex* pulIdx = rclFAry[ulFacetIdx]._aulPoints; - BoundBox3f clBB; - clBB.Add(rclPAry[*(pulIdx++)]); - clBB.Add(rclPAry[*(pulIdx++)]); - clBB.Add(rclPAry[*pulIdx]); - clBB.Enlarge(fMaxDistance); + BoundBox3f clBB; + clBB.Add(rclPAry[*(pulIdx++)]); + clBB.Add(rclPAry[*(pulIdx++)]); + clBB.Add(rclPAry[*pulIdx]); + clBB.Enlarge(fMaxDistance); - if (!clBB.IsInBox(rclPt)) - return false; + if (!clBB.IsInBox(rclPt)) { + return false; + } - rfDistance = _rclMesh.GetFacet(ulFacetIdx).DistanceToPoint(rclPt); + rfDistance = _rclMesh.GetFacet(ulFacetIdx).DistanceToPoint(rclPt); - return rfDistance < fMaxDistance; + return rfDistance < fMaxDistance; } -float MeshAlgorithm::CalculateMinimumGridLength(float fLength, const Base::BoundBox3f& rBBox, unsigned long maxElements) const +float MeshAlgorithm::CalculateMinimumGridLength(float fLength, + const Base::BoundBox3f& rBBox, + unsigned long maxElements) const { - // Max. limit of grid elements - float fMaxGridElements=static_cast(maxElements); + // Max. limit of grid elements + float fMaxGridElements = static_cast(maxElements); - // estimate the minimum allowed grid length - float fMinGridLen = static_cast(pow((rBBox.LengthX()*rBBox.LengthY()*rBBox.LengthZ()/fMaxGridElements), 0.3333f)); - return std::max(fMinGridLen, fLength); + // estimate the minimum allowed grid length + float fMinGridLen = static_cast( + pow((rBBox.LengthX() * rBBox.LengthY() * rBBox.LengthZ() / fMaxGridElements), 0.3333f)); + return std::max(fMinGridLen, fLength); } // ---------------------------------------------------- -void MeshRefPointToFacets::Rebuild () +void MeshRefPointToFacets::Rebuild() { _map.clear(); @@ -1701,7 +1847,8 @@ void MeshRefPointToFacets::Rebuild () _map.resize(rPoints.size()); MeshFacetArray::_TConstIterator pFBegin = rFacets.begin(); - for (MeshFacetArray::_TConstIterator pFIter = rFacets.begin(); pFIter != rFacets.end(); ++pFIter) { + for (MeshFacetArray::_TConstIterator pFIter = rFacets.begin(); pFIter != rFacets.end(); + ++pFIter) { _map[pFIter->_aulPoints[0]].insert(pFIter - pFBegin); _map[pFIter->_aulPoints[1]].insert(pFIter - pFBegin); _map[pFIter->_aulPoints[2]].insert(pFIter - pFBegin); @@ -1722,13 +1869,14 @@ Base::Vector3f MeshRefPointToFacets::GetNormal(PointIndex pos) const return normal; } -std::set MeshRefPointToFacets::NeighbourPoints(const std::vector& pt, int level) const +std::set MeshRefPointToFacets::NeighbourPoints(const std::vector& pt, + int level) const { - std::set cp,nb,lp; + std::set cp, nb, lp; cp.insert(pt.begin(), pt.end()); lp.insert(pt.begin(), pt.end()); MeshFacetArray::_TConstIterator f_it = _rclMesh.GetFacets().begin(); - for (int i=0; i < level; i++) { + for (int i = 0; i < level; i++) { std::set cur; for (PointIndex it : lp) { const std::set& ft = (*this)[it]; @@ -1743,8 +1891,9 @@ std::set MeshRefPointToFacets::NeighbourPoints(const std::vector MeshRefPointToFacets::NeighbourPoints(PointIndex pos) const std::set p; const std::set& vf = _map[pos]; for (FacetIndex it : vf) { - PointIndex p1{}, p2{}, p3{}; + PointIndex p1 {}, p2 {}, p3 {}; _rclMesh.GetFacetPoints(it, p1, p2, p3); - if (p1 != pos) + if (p1 != pos) { p.insert(p1); - if (p2 != pos) + } + if (p2 != pos) { p.insert(p2); - if (p3 != pos) + } + if (p3 != pos) { p.insert(p3); + } } return p; } -void MeshRefPointToFacets::Neighbours (FacetIndex ulFacetInd, float fMaxDist, MeshCollector& collect) const +void MeshRefPointToFacets::Neighbours(FacetIndex ulFacetInd, + float fMaxDist, + MeshCollector& collect) const { std::set visited; - Base::Vector3f clCenter = _rclMesh.GetFacet(ulFacetInd).GetGravityPoint(); + Base::Vector3f clCenter = _rclMesh.GetFacet(ulFacetInd).GetGravityPoint(); const MeshFacetArray& rFacets = _rclMesh.GetFacets(); SearchNeighbours(rFacets, ulFacetInd, clCenter, fMaxDist * fMaxDist, visited, collect); } -void MeshRefPointToFacets::SearchNeighbours(const MeshFacetArray& rFacets, FacetIndex index, const Base::Vector3f &rclCenter, - float fMaxDist2, std::set& visited, MeshCollector& collect) const +void MeshRefPointToFacets::SearchNeighbours(const MeshFacetArray& rFacets, + FacetIndex index, + const Base::Vector3f& rclCenter, + float fMaxDist2, + std::set& visited, + MeshCollector& collect) const { - if (visited.find(index) != visited.end()) + if (visited.find(index) != visited.end()) { return; + } const MeshFacet& face = rFacets[index]; - if (Base::DistanceP2(rclCenter, _rclMesh.GetFacet(face).GetGravityPoint()) > fMaxDist2) + if (Base::DistanceP2(rclCenter, _rclMesh.GetFacet(face).GetGravityPoint()) > fMaxDist2) { return; + } visited.insert(index); collect.Append(_rclMesh, index); for (PointIndex ptIndex : face._aulPoints) { - const std::set &f = (*this)[ptIndex]; + const std::set& f = (*this)[ptIndex]; for (FacetIndex j : f) { SearchNeighbours(rFacets, j, rclCenter, fMaxDist2, visited, collect); @@ -1797,23 +1957,20 @@ void MeshRefPointToFacets::SearchNeighbours(const MeshFacetArray& rFacets, Facet } } -MeshFacetArray::_TConstIterator -MeshRefPointToFacets::GetFacet (FacetIndex index) const +MeshFacetArray::_TConstIterator MeshRefPointToFacets::GetFacet(FacetIndex index) const { return _rclMesh.GetFacets().begin() + index; } -const std::set& -MeshRefPointToFacets::operator[] (PointIndex pos) const +const std::set& MeshRefPointToFacets::operator[](PointIndex pos) const { return _map[pos]; } -std::vector -MeshRefPointToFacets::GetIndices(PointIndex pos1, PointIndex pos2) const +std::vector MeshRefPointToFacets::GetIndices(PointIndex pos1, PointIndex pos2) const { std::vector intersection; - std::back_insert_iterator > result(intersection); + std::back_insert_iterator> result(intersection); const std::set& set1 = _map[pos1]; const std::set& set2 = _map[pos2]; std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(), result); @@ -1824,7 +1981,7 @@ std::vector MeshRefPointToFacets::GetIndices(PointIndex pos1, PointIndex pos2, PointIndex pos3) const { std::vector intersection; - std::back_insert_iterator > result(intersection); + std::back_insert_iterator> result(intersection); std::vector set1 = GetIndices(pos1, pos2); const std::set& set2 = _map[pos3]; std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(), result); @@ -1853,35 +2010,34 @@ void MeshRefPointToFacets::RemoveFacet(FacetIndex facetIndex) //---------------------------------------------------------------------------- -void MeshRefFacetToFacets::Rebuild () +void MeshRefFacetToFacets::Rebuild() { _map.clear(); const MeshFacetArray& rFacets = _rclMesh.GetFacets(); _map.resize(rFacets.size()); - MeshRefPointToFacets vertexFace(_rclMesh); + MeshRefPointToFacets vertexFace(_rclMesh); MeshFacetArray::_TConstIterator pFBegin = rFacets.begin(); for (MeshFacetArray::_TConstIterator pFIter = pFBegin; pFIter != rFacets.end(); ++pFIter) { for (PointIndex ptIndex : pFIter->_aulPoints) { const std::set& faces = vertexFace[ptIndex]; - for (FacetIndex face : faces) + for (FacetIndex face : faces) { _map[pFIter - pFBegin].insert(face); + } } } } -const std::set& -MeshRefFacetToFacets::operator[] (FacetIndex pos) const +const std::set& MeshRefFacetToFacets::operator[](FacetIndex pos) const { return _map[pos]; } -std::vector -MeshRefFacetToFacets::GetIndices(FacetIndex pos1, FacetIndex pos2) const +std::vector MeshRefFacetToFacets::GetIndices(FacetIndex pos1, FacetIndex pos2) const { std::vector intersection; - std::back_insert_iterator > result(intersection); + std::back_insert_iterator> result(intersection); const std::set& set1 = _map[pos1]; const std::set& set2 = _map[pos2]; std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(), result); @@ -1890,7 +2046,7 @@ MeshRefFacetToFacets::GetIndices(FacetIndex pos1, FacetIndex pos2) const //---------------------------------------------------------------------------- -void MeshRefPointToPoints::Rebuild () +void MeshRefPointToPoints::Rebuild() { _map.clear(); @@ -1898,7 +2054,7 @@ void MeshRefPointToPoints::Rebuild () _map.resize(rPoints.size()); const MeshFacetArray& rFacets = _rclMesh.GetFacets(); - for (const auto & rFacet : rFacets) { + for (const auto& rFacet : rFacets) { PointIndex ulP0 = rFacet._aulPoints[0]; PointIndex ulP1 = rFacet._aulPoints[1]; PointIndex ulP2 = rFacet._aulPoints[2]; @@ -1934,17 +2090,16 @@ Base::Vector3f MeshRefPointToPoints::GetNormal(PointIndex pos) const float MeshRefPointToPoints::GetAverageEdgeLength(PointIndex index) const { const MeshPointArray& rPoints = _rclMesh.GetPoints(); - float len=0.0f; + float len = 0.0f; const std::set& n = (*this)[index]; const Base::Vector3f& p = rPoints[index]; for (PointIndex it : n) { len += Base::Distance(p, rPoints[it]); } - return (len/n.size()); + return (len / n.size()); } -const std::set& -MeshRefPointToPoints::operator[] (PointIndex pos) const +const std::set& MeshRefPointToPoints::operator[](PointIndex pos) const { return _map[pos]; } @@ -1961,19 +2116,18 @@ void MeshRefPointToPoints::RemoveNeighbour(PointIndex pos, PointIndex facet) //---------------------------------------------------------------------------- -void MeshRefEdgeToFacets::Rebuild () +void MeshRefEdgeToFacets::Rebuild() { _map.clear(); const MeshFacetArray& rFacets = _rclMesh.GetFacets(); FacetIndex index = 0; for (MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it, ++index) { - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { MeshEdge e; e.first = it->_aulPoints[i]; - e.second = it->_aulPoints[(i+1)%3]; - std::map::iterator jt = - _map.find(e); + e.second = it->_aulPoints[(i + 1) % 3]; + std::map::iterator jt = _map.find(e); if (jt == _map.end()) { _map[e].first = index; _map[e].second = FACET_INDEX_MAX; @@ -1985,15 +2139,14 @@ void MeshRefEdgeToFacets::Rebuild () } } -const std::pair& -MeshRefEdgeToFacets::operator[] (const MeshEdge& edge) const +const std::pair& MeshRefEdgeToFacets::operator[](const MeshEdge& edge) const { return _map.find(edge)->second; } //---------------------------------------------------------------------------- -void MeshRefNormalToPoints::Rebuild () +void MeshRefNormalToPoints::Rebuild() { _norm.clear(); @@ -2001,25 +2154,25 @@ void MeshRefNormalToPoints::Rebuild () _norm.resize(rPoints.size()); const MeshFacetArray& rFacets = _rclMesh.GetFacets(); - for (const auto & rFacet : rFacets) { - const MeshPoint &p0 = rPoints[rFacet._aulPoints[0]]; - const MeshPoint &p1 = rPoints[rFacet._aulPoints[1]]; - const MeshPoint &p2 = rPoints[rFacet._aulPoints[2]]; - float l2p01 = Base::DistanceP2(p0,p1); - float l2p12 = Base::DistanceP2(p1,p2); - float l2p20 = Base::DistanceP2(p2,p0); + for (const auto& rFacet : rFacets) { + const MeshPoint& p0 = rPoints[rFacet._aulPoints[0]]; + const MeshPoint& p1 = rPoints[rFacet._aulPoints[1]]; + const MeshPoint& p2 = rPoints[rFacet._aulPoints[2]]; + float l2p01 = Base::DistanceP2(p0, p1); + float l2p12 = Base::DistanceP2(p1, p2); + float l2p20 = Base::DistanceP2(p2, p0); Base::Vector3f facenormal = _rclMesh.GetFacet(rFacet).GetNormal(); _norm[rFacet._aulPoints[0]] += facenormal * (1.0f / (l2p01 * l2p20)); _norm[rFacet._aulPoints[1]] += facenormal * (1.0f / (l2p12 * l2p01)); _norm[rFacet._aulPoints[2]] += facenormal * (1.0f / (l2p20 * l2p12)); } - for (auto & it : _norm) + for (auto& it : _norm) { it.Normalize(); + } } -const Base::Vector3f& -MeshRefNormalToPoints::operator[] (PointIndex pos) const +const Base::Vector3f& MeshRefNormalToPoints::operator[](PointIndex pos) const { return _norm[pos]; } diff --git a/src/Mod/Mesh/App/Core/Algorithm.h b/src/Mod/Mesh/App/Core/Algorithm.h index 3cf7030c56..a66c9440ee 100644 --- a/src/Mod/Mesh/App/Core/Algorithm.h +++ b/src/Mod/Mesh/App/Core/Algorithm.h @@ -33,12 +33,14 @@ // forward declarations -namespace Base{ - class ViewProjMethod; - class Polygon2d; -} +namespace Base +{ +class ViewProjMethod; +class Polygon2d; +} // namespace Base -namespace MeshCore { +namespace MeshCore +{ class MeshGeomFacet; class MeshGeomEdge; @@ -54,288 +56,367 @@ class AbstractPolygonTriangulator; class MeshExport MeshAlgorithm { public: - explicit MeshAlgorithm (const MeshKernel &rclM) : _rclMesh(rclM) { } + explicit MeshAlgorithm(const MeshKernel& rclM) + : _rclMesh(rclM) + {} public: - /** - * Searches for the nearest facet to the ray defined by - * (\a rclPt, \a rclDir). - * The point \a rclRes holds the intersection point with the ray and the - * nearest facet with index \a rulFacet. - * \note This method tests all facets so it should only be used - * occasionally. - */ - bool NearestFacetOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, Base::Vector3f &rclRes, - FacetIndex &rulFacet) const; - /** - * Searches for the nearest facet to the ray defined by - * (\a rclPt, \a rclDir). - * The point \a rclRes holds the intersection point with the ray and the - * nearest facet with index \a rulFacet. The angle between the ray and the normal of the triangle - * must be less than or equal to \a fMaxAngle. - * \note This method tests all facets so it should only be used - * occasionally. - */ - bool NearestFacetOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, float fMaxAngle, Base::Vector3f &rclRes, - FacetIndex &rulFacet) const; - /** - * Searches for the nearest facet to the ray defined by - * (\a rclPt, \a rclDir). - * The point \a rclRes holds the intersection point with the ray and the - * nearest facet with index \a rulFacet. - * \note This method is optimized by using a grid. So this method can be - * used for a lot of tests. - */ - bool NearestFacetOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, const MeshFacetGrid &rclGrid, - Base::Vector3f &rclRes, FacetIndex &rulFacet) const; - /** - * Searches for the nearest facet to the ray defined by - * (\a rclPt, \a rclDir). - * The point \a rclRes holds the intersection point with the ray and the - * nearest facet with index \a rulFacet. - * \note This method tests all facets taken from \a raulFacets instead of - * the attached mesh. So the caller must ensure that the indices are valid - * facets. - */ - bool NearestFacetOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, const std::vector &raulFacets, - Base::Vector3f &rclRes, FacetIndex &rulFacet) const; - /** - * Searches for the nearest facet to the ray defined by (\a rclPt, \a rclDir). The point \a rclRes holds - * the intersection point with the ray and the nearest facet with index \a rulFacet. - * More a search radius around the ray of \a fMaxSearchArea is defined. - * \note This method is optimized by using a grid. So this method can be used for a lot of tests. - */ - bool NearestFacetOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, float fMaxSearchArea, - const MeshFacetGrid &rclGrid, Base::Vector3f &rclRes, FacetIndex &rulFacet) const; - /** - * Searches for the first facet of the grid element (\a rclGrid) in that the point \a rclPt lies into which is a distance not - * higher than \a fMaxDistance. Of no such facet is found \a rulFacet is undefined and false is returned, otherwise true. - * \note If the point \a rclPt is outside of the grid \a rclGrid nothing is done. - */ - bool FirstFacetToVertex(const Base::Vector3f &rclPt, float fMaxDistance, const MeshFacetGrid &rclGrid, FacetIndex &rulFacet) const; - /** - * Checks from the viewpoint \a rcView if the vertex \a rcVertex is visible or it is hidden by a facet. - * If the vertex is visible true is returned, false otherwise. - */ - bool IsVertexVisible (const Base::Vector3f &rcVertex, const Base::Vector3f &rcView, const MeshFacetGrid &rclGrid ) const; - /** - * Calculates the average length of edges. - */ - float GetAverageEdgeLength() const; - /** - * Calculates the minimum length of edges. - */ - float GetMinimumEdgeLength() const; - /** - * Calculates the maximum length of edges. - */ - float GetMaximumEdgeLength() const; - /** - * Calculates the gravity point of the mesh. - */ - Base::Vector3f GetGravityPoint() const; - /** - * Returns all boundaries of the mesh. - */ - void GetMeshBorders (std::list > &rclBorders) const; - /** - * Returns all boundaries of the mesh. This method does basically the same as above unless that it returns the point indices - * of the boundaries. - */ - void GetMeshBorders (std::list > &rclBorders) const; - /** - * Returns all boundaries of a subset the mesh defined by \a raulInd. - */ - void GetFacetBorders (const std::vector &raulInd, std::list > &rclBorders) const; - /** - * Returns all boundaries of a subset the mesh defined by \a raulInd. This method does basically the same as above unless - * that it returns the point indices of the boundaries. - * If \a ignoreOrientation is false (the default) we may get a broken boundary curve if the mesh has facets - * with wrong orientation. However, if \a ignoreOrientation is true we may get a boundary curve with wrong - * orientation even if the mesh is topologically correct. You should let the default value unless you exactly - * know what you do. - */ - void GetFacetBorders (const std::vector &raulInd, std::list > &rclBorders, - bool ignoreOrientation = false) const; - /** - * Returns the boundary of the mesh to the facet \a uFacet. If this facet does not have an open edge the returned - * boundary is empty. - */ - void GetFacetBorder(FacetIndex uFacet, std::list& rBorder) const; - /** - * Returns the boundary of the mesh to the facets \a uFacest. If none of the facets have an open edge the returned - * boundary is empty. - */ - void GetFacetsBorders(const std::vector& uFacets, std::list >& rBorders) const; - /** - * Boundaries that consist of several loops must be split in several independent boundaries - * to perform e.g. a polygon triangulation algorithm on them. - */ - void SplitBoundaryLoops( std::list >& aBorders ); - /** - * Fills up the single boundary if it is a hole with high quality triangles and a maximum area of \a fMaxArea. - * The triangulation information is stored in \a rFaces and \a rPoints. - * To speed up the calculations the optional parameter \a pStructure can be specified that holds a facet-to-points - * structure of the underlying mesh. - * If the boundary is not a hole or the algorithm failed false is returned, otherwise true. - * @note \a boundary contains the point indices of the mesh data structure. The first and last index must therefore be equal. - * @note \a rPoints contains the geometric points of the triangulation. The number of points can be the same as or exceed - * the number of boundary indices but it cannot be lower. - * @note If the number of geometric points exceeds the number of boundary indices then the triangulation algorithm has - * introduced new points which are added to the end of \a rPoints. - */ - bool FillupHole(const std::vector& boundary, - AbstractPolygonTriangulator& cTria, - MeshFacetArray& rFaces, MeshPointArray& rPoints, - int level, const MeshRefPointToFacets* pP2FStructure=nullptr) const; - /** Sets to all facets in \a raulInds the properties in raulProps. - * \note Both arrays must have the same size. - */ - void SetFacetsProperty(const std::vector &raulInds, const std::vector &raulProps) const; - /** Sets to all facets the flag \a tF. */ - void SetFacetFlag (MeshFacet::TFlagType tF) const; - /** Sets to all points the flag \a tF. */ - void SetPointFlag (MeshPoint::TFlagType tF) const; - /** Resets of all facets the flag \a tF. */ - void ResetFacetFlag (MeshFacet::TFlagType tF) const; - /** Resets of all points the flag \a tF. */ - void ResetPointFlag (MeshPoint::TFlagType tF) const; - /** Sets to all facets in \a raulInds the flag \a tF. */ - void SetFacetsFlag (const std::vector &raulInds, MeshFacet::TFlagType tF) const; - /** Sets to all points in \a raulInds the flag \a tF. */ - void SetPointsFlag (const std::vector &raulInds, MeshPoint::TFlagType tF) const; - /** Gets all facets in \a raulInds with the flag \a tF. */ - void GetFacetsFlag (std::vector &raulInds, MeshFacet::TFlagType tF) const; - /** Gets all points in \a raulInds with the flag \a tF. */ - void GetPointsFlag (std::vector &raulInds, MeshPoint::TFlagType tF) const; - /** Resets from all facets in \a raulInds the flag \a tF. */ - void ResetFacetsFlag (const std::vector &raulInds, MeshFacet::TFlagType tF) const; - /** Resets from all points in \a raulInds the flag \a tF. */ - void ResetPointsFlag (const std::vector &raulInds, MeshPoint::TFlagType tF) const; - /** Count all facets with the flag \a tF. */ - unsigned long CountFacetFlag (MeshFacet::TFlagType tF) const; - /** Count all points with the flag \a tF. */ - unsigned long CountPointFlag (MeshPoint::TFlagType tF) const; - /** Returns all geometric points from the facets in \a rvecIndices. */ - void PointsFromFacetsIndices (const std::vector &rvecIndices, std::vector &rvecPoints) const; - /** - * Returns the indices of all facets that have at least one point that lies inside the tool mesh. The direction - * \a dir is used to try to foraminate the facets of the tool mesh and counts the number of foraminated facets. - * If this number is odd the considered point lies inside otherwise outside. - * @note The tool mesh must be a valid solid. - * @note It's not tested if \a rToolMesh is a valid solid. In case it is not the result is undefined. - */ - void GetFacetsFromToolMesh( const MeshKernel& rToolMesh, const Base::Vector3f& rcDir, std::vector &raclCutted ) const; - /** - * Does basically the same as method above except it uses a mesh grid to speed up the computation. - */ - void GetFacetsFromToolMesh( const MeshKernel& rToolMesh, const Base::Vector3f& rcDir, const MeshFacetGrid& rGrid, std::vector &raclCutted ) const; - /** - * Checks whether the bounding box \a rBox is surrounded by the attached mesh which must be a solid. - * The direction \a rcDir is used to try to foraminate the facets of the tool mesh and counts the number of foraminated facets. - * 1 is returned if the box is completely inside the mesh - * 0 is returned if the box is partially inside (i.e. intersects) the mesh - * -1 is returned if the box is completely outside the mesh. This could also mean that the mesh is surrounded by \a rBox. - */ - int Surround( const Base::BoundBox3f& rBox, const Base::Vector3f& rcDir ); - /** - * Projects the determined facets through projection with \a pclProj into the 2D plane and checks for - * intersection with the polygon. - * If \a bInner is \a true than all facets with at least one corner inside the polygon get deleted. If \a - * bInner is \a false then all facets with at least one corner outside the polygon get deleted. - * This algorithm is optimized by using a grid. - */ - void CheckFacets (const MeshFacetGrid &rclGrid, const Base::ViewProjMethod* pclProj, const Base::Polygon2d& rclPoly, - bool bInner, std::vector &rclRes) const; - /** - * Does the same as the above method unless that it doesn't use a grid. - */ - void CheckFacets (const Base::ViewProjMethod* pclProj, const Base::Polygon2d& rclPoly, - bool bInner, std::vector &rclRes) const; - /** - * Determines all facets of the given array \a raclFacetIndices that lie at the edge or that - * have at least neighbour facet that is not inside the array. The resulting array \a raclResultIndices - * is not be deleted before the algorithm starts. \a usLevel indicates how often the algorithm is - * repeated. - */ - void CheckBorderFacets (const std::vector &raclFacetIndices, - std::vector &raclResultIndices, unsigned short usLevel = 1) const; - /** - * Invokes CheckBorderFacets() to get all border facets of \a raclFacetIndices. Then the content of - * \a raclFacetIndices is replaced by all facets that can be deleted. - * \note The mesh structure is not modified by this method. This is in the responsibility of the user. - */ - void CutBorderFacets (std::vector &raclFacetIndices, unsigned short usLevel = 1) const; - /** Returns the number of border edges */ - unsigned long CountBorderEdges() const; - /** - * Determines all border points as indices of the facets in \a raclFacetIndices. The points are unsorted. - */ - void GetBorderPoints (const std::vector &raclFacetIndices, std::set &raclResultPointsIndices) const; - /** Computes the surface of the mesh. */ - float Surface () const; - /** Subsamples the mesh with point distance \a fDist and stores the points in \a rclPoints. */ - void SubSampleByDist (float fDist, std::vector &rclPoints) const; - /** - * Subsamples the mesh to produce around \a ulCtPoints. \a ulCtPoints should be greater - * than 5 * number of facets. - */ - void SubSampleByCount (unsigned long ulCtPoints, std::vector &rclPoints) const; - /** Returns only the points of the mesh without actually sampling the data. */ - void SubSampleAllPoints(std::vector &rclPoints) const; - /** - * Searches for all facets that intersect the "search tube" with radius \a r around the polyline. - */ - void SearchFacetsFromPolyline (const std::vector &rclPolyline, float fRadius, - const MeshFacetGrid& rclGrid, std::vector &rclResultFacetsIndices) const; - /** Projects a point directly to the mesh (means nearest facet), the result is the facet index and - * the foraminate point, use second version with grid for more performance. - */ - bool NearestPointFromPoint (const Base::Vector3f &rclPt, FacetIndex &rclResFacetIndex, Base::Vector3f &rclResPoint) const; - bool NearestPointFromPoint (const Base::Vector3f &rclPt, const MeshFacetGrid& rclGrid, - FacetIndex &rclResFacetIndex, Base::Vector3f &rclResPoint) const; - bool NearestPointFromPoint (const Base::Vector3f &rclPt, const MeshFacetGrid& rclGrid, float fMaxSearchArea, - FacetIndex &rclResFacetIndex, Base::Vector3f &rclResPoint) const; - /** Cuts the mesh with a plane. The result is a list of polylines. */ - bool CutWithPlane (const Base::Vector3f &clBase, const Base::Vector3f &clNormal, const MeshFacetGrid &rclGrid, - std::list > &rclResult, float fMinEps = 1.0e-2f, bool bConnectPolygons = false) const; - /** - * Gets all facets that cut the plane (N,d) and that lie between the two points left and right. - * The plane is defined by it normalized normal and the signed distance to the origin. - */ - void GetFacetsFromPlane (const MeshFacetGrid &rclGrid, const Base::Vector3f& clNormal, float dist, - const Base::Vector3f &rclLeft, const Base::Vector3f &rclRight, std::vector &rclRes) const; + /** + * Searches for the nearest facet to the ray defined by + * (\a rclPt, \a rclDir). + * The point \a rclRes holds the intersection point with the ray and the + * nearest facet with index \a rulFacet. + * \note This method tests all facets so it should only be used + * occasionally. + */ + bool NearestFacetOnRay(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + Base::Vector3f& rclRes, + FacetIndex& rulFacet) const; + /** + * Searches for the nearest facet to the ray defined by + * (\a rclPt, \a rclDir). + * The point \a rclRes holds the intersection point with the ray and the + * nearest facet with index \a rulFacet. The angle between the ray and the normal of the + * triangle must be less than or equal to \a fMaxAngle. \note This method tests all facets so it + * should only be used occasionally. + */ + bool NearestFacetOnRay(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + float fMaxAngle, + Base::Vector3f& rclRes, + FacetIndex& rulFacet) const; + /** + * Searches for the nearest facet to the ray defined by + * (\a rclPt, \a rclDir). + * The point \a rclRes holds the intersection point with the ray and the + * nearest facet with index \a rulFacet. + * \note This method is optimized by using a grid. So this method can be + * used for a lot of tests. + */ + bool NearestFacetOnRay(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + const MeshFacetGrid& rclGrid, + Base::Vector3f& rclRes, + FacetIndex& rulFacet) const; + /** + * Searches for the nearest facet to the ray defined by + * (\a rclPt, \a rclDir). + * The point \a rclRes holds the intersection point with the ray and the + * nearest facet with index \a rulFacet. + * \note This method tests all facets taken from \a raulFacets instead of + * the attached mesh. So the caller must ensure that the indices are valid + * facets. + */ + bool NearestFacetOnRay(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + const std::vector& raulFacets, + Base::Vector3f& rclRes, + FacetIndex& rulFacet) const; + /** + * Searches for the nearest facet to the ray defined by (\a rclPt, \a rclDir). The point \a + * rclRes holds the intersection point with the ray and the nearest facet with index \a + * rulFacet. More a search radius around the ray of \a fMaxSearchArea is defined. \note This + * method is optimized by using a grid. So this method can be used for a lot of tests. + */ + bool NearestFacetOnRay(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + float fMaxSearchArea, + const MeshFacetGrid& rclGrid, + Base::Vector3f& rclRes, + FacetIndex& rulFacet) const; + /** + * Searches for the first facet of the grid element (\a rclGrid) in that the point \a rclPt lies + * into which is a distance not higher than \a fMaxDistance. Of no such facet is found \a + * rulFacet is undefined and false is returned, otherwise true. \note If the point \a rclPt is + * outside of the grid \a rclGrid nothing is done. + */ + bool FirstFacetToVertex(const Base::Vector3f& rclPt, + float fMaxDistance, + const MeshFacetGrid& rclGrid, + FacetIndex& rulFacet) const; + /** + * Checks from the viewpoint \a rcView if the vertex \a rcVertex is visible or it is hidden by a + * facet. If the vertex is visible true is returned, false otherwise. + */ + bool IsVertexVisible(const Base::Vector3f& rcVertex, + const Base::Vector3f& rcView, + const MeshFacetGrid& rclGrid) const; + /** + * Calculates the average length of edges. + */ + float GetAverageEdgeLength() const; + /** + * Calculates the minimum length of edges. + */ + float GetMinimumEdgeLength() const; + /** + * Calculates the maximum length of edges. + */ + float GetMaximumEdgeLength() const; + /** + * Calculates the gravity point of the mesh. + */ + Base::Vector3f GetGravityPoint() const; + /** + * Returns all boundaries of the mesh. + */ + void GetMeshBorders(std::list>& rclBorders) const; + /** + * Returns all boundaries of the mesh. This method does basically the same as above unless that + * it returns the point indices of the boundaries. + */ + void GetMeshBorders(std::list>& rclBorders) const; + /** + * Returns all boundaries of a subset the mesh defined by \a raulInd. + */ + void GetFacetBorders(const std::vector& raulInd, + std::list>& rclBorders) const; + /** + * Returns all boundaries of a subset the mesh defined by \a raulInd. This method does basically + * the same as above unless that it returns the point indices of the boundaries. If \a + * ignoreOrientation is false (the default) we may get a broken boundary curve if the mesh has + * facets with wrong orientation. However, if \a ignoreOrientation is true we may get a boundary + * curve with wrong orientation even if the mesh is topologically correct. You should let the + * default value unless you exactly know what you do. + */ + void GetFacetBorders(const std::vector& raulInd, + std::list>& rclBorders, + bool ignoreOrientation = false) const; + /** + * Returns the boundary of the mesh to the facet \a uFacet. If this facet does not have an open + * edge the returned boundary is empty. + */ + void GetFacetBorder(FacetIndex uFacet, std::list& rBorder) const; + /** + * Returns the boundary of the mesh to the facets \a uFacest. If none of the facets have an open + * edge the returned boundary is empty. + */ + void GetFacetsBorders(const std::vector& uFacets, + std::list>& rBorders) const; + /** + * Boundaries that consist of several loops must be split in several independent boundaries + * to perform e.g. a polygon triangulation algorithm on them. + */ + void SplitBoundaryLoops(std::list>& aBorders); + /** + * Fills up the single boundary if it is a hole with high quality triangles and a maximum area + * of \a fMaxArea. The triangulation information is stored in \a rFaces and \a rPoints. To speed + * up the calculations the optional parameter \a pStructure can be specified that holds a + * facet-to-points structure of the underlying mesh. If the boundary is not a hole or the + * algorithm failed false is returned, otherwise true. + * @note \a boundary contains the point indices of the mesh data structure. The first and last + * index must therefore be equal. + * @note \a rPoints contains the geometric points of the triangulation. The number of points can + * be the same as or exceed the number of boundary indices but it cannot be lower. + * @note If the number of geometric points exceeds the number of boundary indices then the + * triangulation algorithm has introduced new points which are added to the end of \a rPoints. + */ + bool FillupHole(const std::vector& boundary, + AbstractPolygonTriangulator& cTria, + MeshFacetArray& rFaces, + MeshPointArray& rPoints, + int level, + const MeshRefPointToFacets* pP2FStructure = nullptr) const; + /** Sets to all facets in \a raulInds the properties in raulProps. + * \note Both arrays must have the same size. + */ + void SetFacetsProperty(const std::vector& raulInds, + const std::vector& raulProps) const; + /** Sets to all facets the flag \a tF. */ + void SetFacetFlag(MeshFacet::TFlagType tF) const; + /** Sets to all points the flag \a tF. */ + void SetPointFlag(MeshPoint::TFlagType tF) const; + /** Resets of all facets the flag \a tF. */ + void ResetFacetFlag(MeshFacet::TFlagType tF) const; + /** Resets of all points the flag \a tF. */ + void ResetPointFlag(MeshPoint::TFlagType tF) const; + /** Sets to all facets in \a raulInds the flag \a tF. */ + void SetFacetsFlag(const std::vector& raulInds, MeshFacet::TFlagType tF) const; + /** Sets to all points in \a raulInds the flag \a tF. */ + void SetPointsFlag(const std::vector& raulInds, MeshPoint::TFlagType tF) const; + /** Gets all facets in \a raulInds with the flag \a tF. */ + void GetFacetsFlag(std::vector& raulInds, MeshFacet::TFlagType tF) const; + /** Gets all points in \a raulInds with the flag \a tF. */ + void GetPointsFlag(std::vector& raulInds, MeshPoint::TFlagType tF) const; + /** Resets from all facets in \a raulInds the flag \a tF. */ + void ResetFacetsFlag(const std::vector& raulInds, MeshFacet::TFlagType tF) const; + /** Resets from all points in \a raulInds the flag \a tF. */ + void ResetPointsFlag(const std::vector& raulInds, MeshPoint::TFlagType tF) const; + /** Count all facets with the flag \a tF. */ + unsigned long CountFacetFlag(MeshFacet::TFlagType tF) const; + /** Count all points with the flag \a tF. */ + unsigned long CountPointFlag(MeshPoint::TFlagType tF) const; + /** Returns all geometric points from the facets in \a rvecIndices. */ + void PointsFromFacetsIndices(const std::vector& rvecIndices, + std::vector& rvecPoints) const; + /** + * Returns the indices of all facets that have at least one point that lies inside the tool + * mesh. The direction \a dir is used to try to foraminate the facets of the tool mesh and + * counts the number of foraminated facets. If this number is odd the considered point lies + * inside otherwise outside. + * @note The tool mesh must be a valid solid. + * @note It's not tested if \a rToolMesh is a valid solid. In case it is not the result is + * undefined. + */ + void GetFacetsFromToolMesh(const MeshKernel& rToolMesh, + const Base::Vector3f& rcDir, + std::vector& raclCutted) const; + /** + * Does basically the same as method above except it uses a mesh grid to speed up the + * computation. + */ + void GetFacetsFromToolMesh(const MeshKernel& rToolMesh, + const Base::Vector3f& rcDir, + const MeshFacetGrid& rGrid, + std::vector& raclCutted) const; + /** + * Checks whether the bounding box \a rBox is surrounded by the attached mesh which must be a + * solid. The direction \a rcDir is used to try to foraminate the facets of the tool mesh and + * counts the number of foraminated facets. 1 is returned if the box is completely inside the + * mesh 0 is returned if the box is partially inside (i.e. intersects) the mesh -1 is returned + * if the box is completely outside the mesh. This could also mean that the mesh is surrounded + * by \a rBox. + */ + int Surround(const Base::BoundBox3f& rBox, const Base::Vector3f& rcDir); + /** + * Projects the determined facets through projection with \a pclProj into the 2D plane and + * checks for intersection with the polygon. If \a bInner is \a true than all facets with at + * least one corner inside the polygon get deleted. If \a bInner is \a false then all facets + * with at least one corner outside the polygon get deleted. This algorithm is optimized by + * using a grid. + */ + void CheckFacets(const MeshFacetGrid& rclGrid, + const Base::ViewProjMethod* pclProj, + const Base::Polygon2d& rclPoly, + bool bInner, + std::vector& rclRes) const; + /** + * Does the same as the above method unless that it doesn't use a grid. + */ + void CheckFacets(const Base::ViewProjMethod* pclProj, + const Base::Polygon2d& rclPoly, + bool bInner, + std::vector& rclRes) const; + /** + * Determines all facets of the given array \a raclFacetIndices that lie at the edge or that + * have at least neighbour facet that is not inside the array. The resulting array \a + * raclResultIndices is not be deleted before the algorithm starts. \a usLevel indicates how + * often the algorithm is repeated. + */ + void CheckBorderFacets(const std::vector& raclFacetIndices, + std::vector& raclResultIndices, + unsigned short usLevel = 1) const; + /** + * Invokes CheckBorderFacets() to get all border facets of \a raclFacetIndices. Then the content + * of \a raclFacetIndices is replaced by all facets that can be deleted. \note The mesh + * structure is not modified by this method. This is in the responsibility of the user. + */ + void CutBorderFacets(std::vector& raclFacetIndices, + unsigned short usLevel = 1) const; + /** Returns the number of border edges */ + unsigned long CountBorderEdges() const; + /** + * Determines all border points as indices of the facets in \a raclFacetIndices. The points are + * unsorted. + */ + void GetBorderPoints(const std::vector& raclFacetIndices, + std::set& raclResultPointsIndices) const; + /** Computes the surface of the mesh. */ + float Surface() const; + /** Subsamples the mesh with point distance \a fDist and stores the points in \a rclPoints. */ + void SubSampleByDist(float fDist, std::vector& rclPoints) const; + /** + * Subsamples the mesh to produce around \a ulCtPoints. \a ulCtPoints should be greater + * than 5 * number of facets. + */ + void SubSampleByCount(unsigned long ulCtPoints, std::vector& rclPoints) const; + /** Returns only the points of the mesh without actually sampling the data. */ + void SubSampleAllPoints(std::vector& rclPoints) const; + /** + * Searches for all facets that intersect the "search tube" with radius \a r around the + * polyline. + */ + void SearchFacetsFromPolyline(const std::vector& rclPolyline, + float fRadius, + const MeshFacetGrid& rclGrid, + std::vector& rclResultFacetsIndices) const; + /** Projects a point directly to the mesh (means nearest facet), the result is the facet index + * and the foraminate point, use second version with grid for more performance. + */ + bool NearestPointFromPoint(const Base::Vector3f& rclPt, + FacetIndex& rclResFacetIndex, + Base::Vector3f& rclResPoint) const; + bool NearestPointFromPoint(const Base::Vector3f& rclPt, + const MeshFacetGrid& rclGrid, + FacetIndex& rclResFacetIndex, + Base::Vector3f& rclResPoint) const; + bool NearestPointFromPoint(const Base::Vector3f& rclPt, + const MeshFacetGrid& rclGrid, + float fMaxSearchArea, + FacetIndex& rclResFacetIndex, + Base::Vector3f& rclResPoint) const; + /** Cuts the mesh with a plane. The result is a list of polylines. */ + bool CutWithPlane(const Base::Vector3f& clBase, + const Base::Vector3f& clNormal, + const MeshFacetGrid& rclGrid, + std::list>& rclResult, + float fMinEps = 1.0e-2f, + bool bConnectPolygons = false) const; + /** + * Gets all facets that cut the plane (N,d) and that lie between the two points left and right. + * The plane is defined by it normalized normal and the signed distance to the origin. + */ + void GetFacetsFromPlane(const MeshFacetGrid& rclGrid, + const Base::Vector3f& clNormal, + float dist, + const Base::Vector3f& rclLeft, + const Base::Vector3f& rclRight, + std::vector& rclRes) const; - /** Returns true if the distance from the \a rclPt to the facet \a ulFacetIdx is less than \a fMaxDistance. - * If this restriction is met \a rfDistance is set to the actual distance, otherwise false is returned. - */ - bool Distance (const Base::Vector3f &rclPt, FacetIndex ulFacetIdx, float fMaxDistance, float &rfDistance) const; - /** - * Calculates the minimum grid length so that not more elements than \a maxElements will be created when the grid gets - * built up. The minimum grid length must be at least \a fLength. - */ - float CalculateMinimumGridLength(float fLength, const Base::BoundBox3f& rBBox, unsigned long maxElements) const; + /** Returns true if the distance from the \a rclPt to the facet \a ulFacetIdx is less than \a + * fMaxDistance. If this restriction is met \a rfDistance is set to the actual distance, + * otherwise false is returned. + */ + bool Distance(const Base::Vector3f& rclPt, + FacetIndex ulFacetIdx, + float fMaxDistance, + float& rfDistance) const; + /** + * Calculates the minimum grid length so that not more elements than \a maxElements will be + * created when the grid gets built up. The minimum grid length must be at least \a fLength. + */ + float CalculateMinimumGridLength(float fLength, + const Base::BoundBox3f& rBBox, + unsigned long maxElements) const; protected: - /** Helper method to connect the intersection points to polylines. */ - bool ConnectLines (std::list > &rclLines, std::list >&rclPolylines, - float fMinEps) const; - bool ConnectPolygons(std::list > &clPolyList, std::list > &rclLines) const; - /** Searches the nearest facet in \a raulFacets to the ray (\a rclPt, \a rclDir). */ - bool RayNearestField (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, const std::vector &raulFacets, - Base::Vector3f &rclRes, FacetIndex &rulFacet, float fMaxAngle = Mathf::PI) const; - /** - * Splits the boundary \a rBound in several loops and append this loops to the list of borders. - */ - void SplitBoundaryLoops(const std::vector& rBound, std::list >& aBorders); - /** - * From the given \a openEdges a boundary is split and added to \a boundary. - */ - void SplitBoundaryFromOpenEdges(std::list >& openEdges, std::list& boundary) const; + /** Helper method to connect the intersection points to polylines. */ + bool ConnectLines(std::list>& rclLines, + std::list>& rclPolylines, + float fMinEps) const; + bool ConnectPolygons(std::list>& clPolyList, + std::list>& rclLines) const; + /** Searches the nearest facet in \a raulFacets to the ray (\a rclPt, \a rclDir). */ + bool RayNearestField(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + const std::vector& raulFacets, + Base::Vector3f& rclRes, + FacetIndex& rulFacet, + float fMaxAngle = Mathf::PI) const; + /** + * Splits the boundary \a rBound in several loops and append this loops to the list of borders. + */ + void SplitBoundaryLoops(const std::vector& rBound, + std::list>& aBorders); + /** + * From the given \a openEdges a boundary is split and added to \a boundary. + */ + void SplitBoundaryFromOpenEdges(std::list>& openEdges, + std::list& boundary) const; protected: - const MeshKernel &_rclMesh; /**< The mesh kernel. */ + const MeshKernel& _rclMesh; /**< The mesh kernel. */ }; class MeshExport MeshCollector @@ -346,10 +427,12 @@ public: virtual void Append(const MeshCore::MeshKernel&, FacetIndex index) = 0; }; -class MeshExport PointCollector : public MeshCollector +class MeshExport PointCollector: public MeshCollector { public: - explicit PointCollector(std::vector& ind) : indices(ind){} + explicit PointCollector(std::vector& ind) + : indices(ind) + {} void Append(const MeshCore::MeshKernel& kernel, FacetIndex index) override { PointIndex ulP1, ulP2, ulP3; @@ -363,10 +446,12 @@ private: std::vector& indices; }; -class MeshExport FacetCollector : public MeshCollector +class MeshExport FacetCollector: public MeshCollector { public: - explicit FacetCollector(std::vector& ind) : indices(ind){} + explicit FacetCollector(std::vector& ind) + : indices(ind) + {} void Append(const MeshCore::MeshKernel&, FacetIndex index) override { indices.push_back(index); @@ -386,30 +471,37 @@ class MeshExport MeshRefPointToFacets { public: /// Construction - explicit MeshRefPointToFacets (const MeshKernel &rclM) : _rclMesh(rclM) - { Rebuild(); } + explicit MeshRefPointToFacets(const MeshKernel& rclM) + : _rclMesh(rclM) + { + Rebuild(); + } /// Rebuilds up data structure - void Rebuild (); - const std::set& operator[] (PointIndex) const; + void Rebuild(); + const std::set& operator[](PointIndex) const; std::vector GetIndices(PointIndex, PointIndex) const; std::vector GetIndices(PointIndex, PointIndex, PointIndex) const; - MeshFacetArray::_TConstIterator GetFacet (FacetIndex) const; - std::set NeighbourPoints(const std::vector& , int level) const; + MeshFacetArray::_TConstIterator GetFacet(FacetIndex) const; + std::set NeighbourPoints(const std::vector&, int level) const; std::set NeighbourPoints(PointIndex) const; - void Neighbours (FacetIndex ulFacetInd, float fMaxDist, MeshCollector& collect) const; + void Neighbours(FacetIndex ulFacetInd, float fMaxDist, MeshCollector& collect) const; Base::Vector3f GetNormal(PointIndex) const; void AddNeighbour(PointIndex, FacetIndex); void RemoveNeighbour(PointIndex, FacetIndex); void RemoveFacet(FacetIndex); protected: - void SearchNeighbours(const MeshFacetArray& rFacets, FacetIndex index, const Base::Vector3f &rclCenter, - float fMaxDist, std::set &visit, MeshCollector& collect) const; + void SearchNeighbours(const MeshFacetArray& rFacets, + FacetIndex index, + const Base::Vector3f& rclCenter, + float fMaxDist, + std::set& visit, + MeshCollector& collect) const; protected: - const MeshKernel &_rclMesh; /**< The mesh kernel. */ - std::vector > _map; + const MeshKernel& _rclMesh; /**< The mesh kernel. */ + std::vector> _map; }; /** @@ -422,20 +514,23 @@ class MeshExport MeshRefFacetToFacets { public: /// Construction - explicit MeshRefFacetToFacets (const MeshKernel &rclM) : _rclMesh(rclM) - { Rebuild(); } + explicit MeshRefFacetToFacets(const MeshKernel& rclM) + : _rclMesh(rclM) + { + Rebuild(); + } /// Rebuilds up data structure - void Rebuild (); + void Rebuild(); /// Returns a set of facets sharing one or more points with the facet with /// index \a ulFacetIndex. - const std::set& operator[] (FacetIndex) const; + const std::set& operator[](FacetIndex) const; /// Returns an array of common facets of the passed facet indexes. std::vector GetIndices(FacetIndex, FacetIndex) const; protected: - const MeshKernel &_rclMesh; /**< The mesh kernel. */ - std::vector > _map; + const MeshKernel& _rclMesh; /**< The mesh kernel. */ + std::vector> _map; }; /** @@ -448,20 +543,23 @@ class MeshExport MeshRefPointToPoints { public: /// Construction - explicit MeshRefPointToPoints (const MeshKernel &rclM) : _rclMesh(rclM) - { Rebuild(); } + explicit MeshRefPointToPoints(const MeshKernel& rclM) + : _rclMesh(rclM) + { + Rebuild(); + } /// Rebuilds up data structure - void Rebuild (); - const std::set& operator[] (PointIndex) const; + void Rebuild(); + const std::set& operator[](PointIndex) const; Base::Vector3f GetNormal(PointIndex) const; float GetAverageEdgeLength(PointIndex) const; void AddNeighbour(PointIndex, PointIndex); void RemoveNeighbour(PointIndex, PointIndex); protected: - const MeshKernel &_rclMesh; /**< The mesh kernel. */ - std::vector > _map; + const MeshKernel& _rclMesh; /**< The mesh kernel. */ + std::vector> _map; }; /** @@ -474,30 +572,38 @@ class MeshExport MeshRefEdgeToFacets { public: /// Construction - explicit MeshRefEdgeToFacets (const MeshKernel &rclM) : _rclMesh(rclM) - { Rebuild(); } + explicit MeshRefEdgeToFacets(const MeshKernel& rclM) + : _rclMesh(rclM) + { + Rebuild(); + } /// Rebuilds up data structure - void Rebuild (); - const std::pair& operator[] (const MeshEdge&) const; + void Rebuild(); + const std::pair& operator[](const MeshEdge&) const; protected: - class EdgeOrder { + class EdgeOrder + { public: - bool operator () (const MeshEdge &e1, const MeshEdge &e2) const + bool operator()(const MeshEdge& e1, const MeshEdge& e2) const { - if (e1.first < e2.first) + if (e1.first < e2.first) { return true; - else if (e1.first > e2.first) + } + else if (e1.first > e2.first) { return false; - else if (e1.second < e2.second) + } + else if (e1.second < e2.second) { return true; - else + } + else { return false; + } } }; using MeshFacetPair = std::pair; - const MeshKernel &_rclMesh; /**< The mesh kernel. */ + const MeshKernel& _rclMesh; /**< The mesh kernel. */ std::map _map; }; @@ -510,21 +616,25 @@ class MeshExport MeshRefNormalToPoints { public: /// Construction - explicit MeshRefNormalToPoints (const MeshKernel &rclM) : _rclMesh(rclM) - { Rebuild(); } + explicit MeshRefNormalToPoints(const MeshKernel& rclM) + : _rclMesh(rclM) + { + Rebuild(); + } /// Rebuilds up data structure - void Rebuild (); - const Base::Vector3f& operator[] (PointIndex) const; - const std::vector& GetValues() const { + void Rebuild(); + const Base::Vector3f& operator[](PointIndex) const; + const std::vector& GetValues() const + { return _norm; } protected: - const MeshKernel &_rclMesh; /**< The mesh kernel. */ + const MeshKernel& _rclMesh; /**< The mesh kernel. */ std::vector _norm; }; -} // namespace MeshCore +} // namespace MeshCore #endif // MESH_ALGORITHM_H diff --git a/src/Mod/Mesh/App/Core/Approximation.cpp b/src/Mod/Mesh/App/Core/Approximation.cpp index e1b73e66e1..ad204d493a 100644 --- a/src/Mod/Mesh/App/Core/Approximation.cpp +++ b/src/Mod/Mesh/App/Core/Approximation.cpp @@ -23,23 +23,23 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include +#include +#include +#include #endif #include #include -#include #include #include #include +#include -//#define FC_USE_EIGEN -#include +// #define FC_USE_EIGEN #include +#include #ifdef FC_USE_EIGEN -# include +#include #endif #include "Approximation.h" @@ -58,40 +58,40 @@ Approximation::~Approximation() Clear(); } -void Approximation::GetMgcVectorArray(std::vector< Wm4::Vector3 >& rcPts) const +void Approximation::GetMgcVectorArray(std::vector>& rcPts) const { - std::list< Base::Vector3f >::const_iterator It; + std::list::const_iterator It; rcPts.reserve(_vPoints.size()); for (It = _vPoints.begin(); It != _vPoints.end(); ++It) { rcPts.push_back(Base::convertTo(*It)); } } -void Approximation::AddPoint(const Base::Vector3f &rcVector) +void Approximation::AddPoint(const Base::Vector3f& rcVector) { _vPoints.push_back(rcVector); _bIsFitted = false; } -void Approximation::AddPoints(const std::vector &points) +void Approximation::AddPoints(const std::vector& points) { std::copy(points.begin(), points.end(), std::back_inserter(_vPoints)); _bIsFitted = false; } -void Approximation::AddPoints(const std::set &points) +void Approximation::AddPoints(const std::set& points) { std::copy(points.begin(), points.end(), std::back_inserter(_vPoints)); _bIsFitted = false; } -void Approximation::AddPoints(const std::list &points) +void Approximation::AddPoints(const std::list& points) { std::copy(points.begin(), points.end(), std::back_inserter(_vPoints)); _bIsFitted = false; } -void Approximation::AddPoints(const MeshPointArray &points) +void Approximation::AddPoints(const MeshPointArray& points) { std::copy(points.begin(), points.end(), std::back_inserter(_vPoints)); _bIsFitted = false; @@ -101,8 +101,9 @@ Base::Vector3f Approximation::GetGravity() const { Base::Vector3f clGravity; if (!_vPoints.empty()) { - for (const auto& vPoint : _vPoints) + for (const auto& vPoint : _vPoints) { clGravity += vPoint; + } clGravity *= 1.0f / float(_vPoints.size()); } return clGravity; @@ -132,45 +133,53 @@ bool Approximation::Done() const // ------------------------------------------------------------------------------- PlaneFit::PlaneFit() - : _vBase(0,0,0) - , _vDirU(1,0,0) - , _vDirV(0,1,0) - , _vDirW(0,0,1) -{ -} + : _vBase(0, 0, 0) + , _vDirU(1, 0, 0) + , _vDirV(0, 1, 0) + , _vDirW(0, 0, 1) +{} float PlaneFit::Fit() { _bIsFitted = true; - if (CountPoints() < 3) + if (CountPoints() < 3) { return FLOAT_MAX; + } - double sxx,sxy,sxz,syy,syz,szz,mx,my,mz; - sxx=sxy=sxz=syy=syz=szz=mx=my=mz=0.0; + double sxx, sxy, sxz, syy, syz, szz, mx, my, mz; + sxx = sxy = sxz = syy = syz = szz = mx = my = mz = 0.0; - for (const auto & vPoint : _vPoints) { - sxx += double(vPoint.x * vPoint.x); sxy += double(vPoint.x * vPoint.y); - sxz += double(vPoint.x * vPoint.z); syy += double(vPoint.y * vPoint.y); - syz += double(vPoint.y * vPoint.z); szz += double(vPoint.z * vPoint.z); - mx += double(vPoint.x); my += double(vPoint.y); mz += double(vPoint.z); + for (const auto& vPoint : _vPoints) { + sxx += double(vPoint.x * vPoint.x); + sxy += double(vPoint.x * vPoint.y); + sxz += double(vPoint.x * vPoint.z); + syy += double(vPoint.y * vPoint.y); + syz += double(vPoint.y * vPoint.z); + szz += double(vPoint.z * vPoint.z); + mx += double(vPoint.x); + my += double(vPoint.y); + mz += double(vPoint.z); } size_t nSize = _vPoints.size(); - sxx = sxx - mx*mx/(double(nSize)); - sxy = sxy - mx*my/(double(nSize)); - sxz = sxz - mx*mz/(double(nSize)); - syy = syy - my*my/(double(nSize)); - syz = syz - my*mz/(double(nSize)); - szz = szz - mz*mz/(double(nSize)); + sxx = sxx - mx * mx / (double(nSize)); + sxy = sxy - mx * my / (double(nSize)); + sxz = sxz - mx * mz / (double(nSize)); + syy = syy - my * my / (double(nSize)); + syz = syz - my * mz / (double(nSize)); + szz = szz - mz * mz / (double(nSize)); #if defined(FC_USE_EIGEN) Eigen::Matrix3d covMat = Eigen::Matrix3d::Zero(); - covMat(0,0) = sxx; - covMat(1,1) = syy; - covMat(2,2) = szz; - covMat(0,1) = sxy; covMat(1,0) = sxy; - covMat(0,2) = sxz; covMat(2,0) = sxz; - covMat(1,2) = syz; covMat(2,1) = syz; + covMat(0, 0) = sxx; + covMat(1, 1) = syy; + covMat(2, 2) = szz; + covMat(0, 1) = sxy; + covMat(1, 0) = sxy; + covMat(0, 2) = sxz; + covMat(2, 0) = sxz; + covMat(1, 2) = syz; + covMat(2, 1) = syz; Eigen::SelfAdjointEigenSolver eig(covMat); Eigen::Vector3d u = eig.eigenvectors().col(1); @@ -180,12 +189,12 @@ float PlaneFit::Fit() _vDirU.Set(u.x(), u.y(), u.z()); _vDirV.Set(v.x(), v.y(), v.z()); _vDirW.Set(w.x(), w.y(), w.z()); - _vBase.Set(mx/(float)nSize, my/(float)nSize, mz/(float)nSize); + _vBase.Set(mx / (float)nSize, my / (float)nSize, mz / (float)nSize); float sigma = w.dot(covMat * w); #else // Covariance matrix - Wm4::Matrix3 akMat(sxx,sxy,sxz,sxy,syy,syz,sxz,syz,szz); + Wm4::Matrix3 akMat(sxx, sxy, sxz, sxy, syy, syz, sxz, syz, szz); Wm4::Matrix3 rkRot, rkDiag; try { akMat.EigenDecomposition(rkRot, rkDiag); @@ -198,17 +207,19 @@ float PlaneFit::Fit() // rkDiag(0,0) <= rkDiag(1,1) <= rkDiag(2,2) // // points describe a line or even are identical - if (rkDiag(1,1) <= 0) + if (rkDiag(1, 1) <= 0) { return FLOAT_MAX; + } Wm4::Vector3 U = rkRot.GetColumn(1); Wm4::Vector3 V = rkRot.GetColumn(2); Wm4::Vector3 W = rkRot.GetColumn(0); // It may happen that the result have nan values - for (int i=0; i<3; i++) { - if (boost::math::isnan(W[i])) + for (int i = 0; i < 3; i++) { + if (boost::math::isnan(W[i])) { return FLOAT_MAX; + } } // In some cases when the points exactly lie on a plane it can happen that @@ -216,8 +227,7 @@ float PlaneFit::Fit() // In this case create an orthonormal basis bool validUV = true; for (int i = 0; i < 3; i++) { - if (boost::math::isnan(U[i]) || - boost::math::isnan(V[i])) { + if (boost::math::isnan(U[i]) || boost::math::isnan(V[i])) { validUV = false; break; } @@ -230,18 +240,20 @@ float PlaneFit::Fit() _vDirU.Set(float(U.X()), float(U.Y()), float(U.Z())); _vDirV.Set(float(V.X()), float(V.Y()), float(V.Z())); _vDirW.Set(float(W.X()), float(W.Y()), float(W.Z())); - _vBase.Set(float(mx/nSize), float(my/nSize), float(mz/nSize)); + _vBase.Set(float(mx / nSize), float(my / nSize), float(mz / nSize)); float sigma = float(W.Dot(akMat * W)); #endif // In case sigma is nan - if (boost::math::isnan(sigma)) + if (boost::math::isnan(sigma)) { return FLOAT_MAX; + } // This must be caused by some round-off errors. Theoretically it's impossible // that 'sigma' becomes negative because the covariance matrix is positive semi-definite. - if (sigma < 0) + if (sigma < 0) { sigma = 0; + } // make a right-handed system if ((_vDirU % _vDirV) * _vDirW < 0.0f) { @@ -250,10 +262,12 @@ float PlaneFit::Fit() _vDirV = tmp; } - if (nSize > 3) - sigma = sqrt(sigma/(nSize-3)); - else + if (nSize > 3) { + sigma = sqrt(sigma / (nSize - 3)); + } + else { sigma = 0; + } _fLastResult = sigma; return _fLastResult; @@ -261,41 +275,50 @@ float PlaneFit::Fit() Base::Vector3f PlaneFit::GetBase() const { - if (_bIsFitted) + if (_bIsFitted) { return _vBase; - else + } + else { return Base::Vector3f(); + } } Base::Vector3f PlaneFit::GetDirU() const { - if (_bIsFitted) + if (_bIsFitted) { return _vDirU; - else + } + else { return Base::Vector3f(); + } } Base::Vector3f PlaneFit::GetDirV() const { - if (_bIsFitted) + if (_bIsFitted) { return _vDirV; - else + } + else { return Base::Vector3f(); + } } Base::Vector3f PlaneFit::GetNormal() const { - if (_bIsFitted) + if (_bIsFitted) { return _vDirW; - else + } + else { return Base::Vector3f(); + } } -float PlaneFit::GetDistanceToPlane(const Base::Vector3f &rcPoint) const +float PlaneFit::GetDistanceToPlane(const Base::Vector3f& rcPoint) const { float fResult = FLOAT_MAX; - if (_bIsFitted) + if (_bIsFitted) { fResult = (rcPoint - _vBase) * _vDirW; + } return fResult; } @@ -305,19 +328,19 @@ float PlaneFit::GetStdDeviation() const // Variance: VAR=(N/N-1)*[(1/N)*SUM(Xi^2)-M^2] // Standard deviation: SD=SQRT(VAR) // Standard error of the mean: SE=SD/SQRT(N) - if (!_bIsFitted) + if (!_bIsFitted) { return FLOAT_MAX; + } - float fSumXi = 0.0f, fSumXi2 = 0.0f, - fMean = 0.0f, fDist = 0.0f; + float fSumXi = 0.0f, fSumXi2 = 0.0f, fMean = 0.0f, fDist = 0.0f; float ulPtCt = float(CountPoints()); - std::list< Base::Vector3f >::const_iterator cIt; + std::list::const_iterator cIt; for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) { - fDist = GetDistanceToPlane( *cIt ); - fSumXi += fDist; - fSumXi2 += ( fDist * fDist ); + fDist = GetDistanceToPlane(*cIt); + fSumXi += fDist; + fSumXi2 += (fDist * fDist); } fMean = (1.0f / ulPtCt) * fSumXi; @@ -329,19 +352,20 @@ float PlaneFit::GetSignedStdDeviation() const // if the nearest point to the gravity is at the side // of normal direction the value will be // positive otherwise negative - if (!_bIsFitted) + if (!_bIsFitted) { return FLOAT_MAX; + } - float fSumXi = 0.0f, fSumXi2 = 0.0f, - fMean = 0.0f, fDist = 0.0f; + float fSumXi = 0.0f, fSumXi2 = 0.0f, fMean = 0.0f, fDist = 0.0f; float fMinDist = FLOAT_MAX; float fFactor; float ulPtCt = float(CountPoints()); Base::Vector3f clGravity, clPt; std::list::const_iterator cIt; - for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) + for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) { clGravity += *cIt; + } clGravity *= (1.0f / ulPtCt); for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) { @@ -350,27 +374,29 @@ float PlaneFit::GetSignedStdDeviation() const clPt = *cIt; } fDist = GetDistanceToPlane(*cIt); - fSumXi += fDist; + fSumXi += fDist; fSumXi2 += (fDist * fDist); } // which side - if ((clPt-clGravity)*GetNormal() > 0) + if ((clPt - clGravity) * GetNormal() > 0) { fFactor = 1.0f; - else + } + else { fFactor = -1.0f; + } fMean = 1.0f / ulPtCt * fSumXi; return fFactor * sqrt((ulPtCt / (ulPtCt - 3.0f)) * ((1.0f / ulPtCt) * fSumXi2 - fMean * fMean)); } -void PlaneFit::ProjectToPlane () +void PlaneFit::ProjectToPlane() { Base::Vector3f cGravity(GetGravity()); - Base::Vector3f cNormal (GetNormal ()); + Base::Vector3f cNormal(GetNormal()); - for (auto & cPnt : _vPoints) { + for (auto& cPnt : _vPoints) { float fD = (cPnt - cGravity) * cNormal; cPnt = cPnt - fD * cNormal; } @@ -401,13 +427,15 @@ std::vector PlaneFit::GetLocalPoints() const Base::Vector3d bs = Base::convertTo(this->_vBase); Base::Vector3d ex = Base::convertTo(this->_vDirU); Base::Vector3d ey = Base::convertTo(this->_vDirV); - //Base::Vector3d ez = Base::convertTo(this->_vDirW); + // Base::Vector3d ez = Base::convertTo(this->_vDirW); localPoints.insert(localPoints.begin(), _vPoints.begin(), _vPoints.end()); - for (auto & localPoint : localPoints) { + for (auto& localPoint : localPoints) { Base::Vector3d clPoint = Base::convertTo(localPoint); clPoint.TransformToCoordinateSystem(bs, ex, ey); - localPoint.Set(static_cast(clPoint.x), static_cast(clPoint.y), static_cast(clPoint.z)); + localPoint.Set(static_cast(clPoint.x), + static_cast(clPoint.y), + static_cast(clPoint.z)); } } @@ -418,26 +446,32 @@ Base::BoundBox3f PlaneFit::GetBoundings() const { Base::BoundBox3f bbox; std::vector pts = GetLocalPoints(); - for (const auto& it : pts) + for (const auto& it : pts) { bbox.Add(it); + } return bbox; } // ------------------------------------------------------------------------------- -bool QuadraticFit::GetCurvatureInfo(double x, double y, double z, - double &rfCurv0, double &rfCurv1, - Base::Vector3f &rkDir0, Base::Vector3f &rkDir1, double &dDistance) +bool QuadraticFit::GetCurvatureInfo(double x, + double y, + double z, + double& rfCurv0, + double& rfCurv1, + Base::Vector3f& rkDir0, + Base::Vector3f& rkDir1, + double& dDistance) { - assert( _bIsFitted ); + assert(_bIsFitted); bool bResult = false; if (_bIsFitted) { Wm4::Vector3 Dir0, Dir1; - FunctionContainer clFuncCont( _fCoeff ); - bResult = clFuncCont.CurvatureInfo( x, y, z, rfCurv0, rfCurv1, Dir0, Dir1, dDistance ); + FunctionContainer clFuncCont(_fCoeff); + bResult = clFuncCont.CurvatureInfo(x, y, z, rfCurv0, rfCurv1, Dir0, Dir1, dDistance); - dDistance = double(clFuncCont.GetGradient( x, y, z ).Length()); + dDistance = double(clFuncCont.GetGradient(x, y, z).Length()); rkDir0 = Base::convertTo(Dir0); rkDir1 = Base::convertTo(Dir1); } @@ -445,13 +479,13 @@ bool QuadraticFit::GetCurvatureInfo(double x, double y, double z, return bResult; } -bool QuadraticFit::GetCurvatureInfo(double x, double y, double z, double &rfCurv0, double &rfCurv1) +bool QuadraticFit::GetCurvatureInfo(double x, double y, double z, double& rfCurv0, double& rfCurv1) { bool bResult = false; if (_bIsFitted) { - FunctionContainer clFuncCont( _fCoeff ); - bResult = clFuncCont.CurvatureInfo( x, y, z, rfCurv0, rfCurv1 ); + FunctionContainer clFuncCont(_fCoeff); + bResult = clFuncCont.CurvatureInfo(x, y, z, rfCurv0, rfCurv1); } return bResult; @@ -466,10 +500,12 @@ double QuadraticFit::GetCoeff(std::size_t ulIndex) const { assert(ulIndex < 10); - if( _bIsFitted ) - return _fCoeff[ ulIndex ]; - else + if (_bIsFitted) { + return _fCoeff[ulIndex]; + } + else { return double(FLOAT_MAX); + } } float QuadraticFit::Fit() @@ -477,9 +513,9 @@ float QuadraticFit::Fit() float fResult = FLOAT_MAX; if (CountPoints() > 0) { - std::vector< Wm4::Vector3 > cPts; - GetMgcVectorArray( cPts ); - fResult = (float) Wm4::QuadraticFit3( CountPoints(), &(cPts[0]), _fCoeff ); + std::vector> cPts; + GetMgcVectorArray(cPts); + fResult = (float)Wm4::QuadraticFit3(CountPoints(), &(cPts[0]), _fCoeff); _fLastResult = fResult; _bIsFitted = true; @@ -488,13 +524,18 @@ float QuadraticFit::Fit() return fResult; } -void QuadraticFit::CalcEigenValues(double &dLambda1, double &dLambda2, double &dLambda3, - Base::Vector3f &clEV1, Base::Vector3f &clEV2, Base::Vector3f &clEV3) const +void QuadraticFit::CalcEigenValues(double& dLambda1, + double& dLambda2, + double& dLambda3, + Base::Vector3f& clEV1, + Base::Vector3f& clEV2, + Base::Vector3f& clEV3) const { - assert( _bIsFitted ); + assert(_bIsFitted); /* - * F(x,y,z) = a11*x*x + a22*y*y + a33*z*z +2*a12*x*y + 2*a13*x*z + 2*a23*y*z + 2*a10*x + 2*a20*y + 2*a30*z * a00 = 0 + * F(x,y,z) = a11*x*x + a22*y*y + a33*z*z +2*a12*x*y + 2*a13*x*z + 2*a23*y*z + 2*a10*x + 2*a20*y + * + 2*a30*z * a00 = 0 * * Form matrix: * @@ -514,12 +555,18 @@ void QuadraticFit::CalcEigenValues(double &dLambda1, double &dLambda2, double &d * */ - Wm4::Matrix3 akMat(_fCoeff[4], _fCoeff[7]/2.0, _fCoeff[8]/2.0, - _fCoeff[7]/2.0, _fCoeff[5], _fCoeff[9]/2.0, - _fCoeff[8]/2.0, _fCoeff[9]/2.0, _fCoeff[6] ); + Wm4::Matrix3 akMat(_fCoeff[4], + _fCoeff[7] / 2.0, + _fCoeff[8] / 2.0, + _fCoeff[7] / 2.0, + _fCoeff[5], + _fCoeff[9] / 2.0, + _fCoeff[8] / 2.0, + _fCoeff[9] / 2.0, + _fCoeff[6]); Wm4::Matrix3 rkRot, rkDiag; - akMat.EigenDecomposition( rkRot, rkDiag ); + akMat.EigenDecomposition(rkRot, rkDiag); Wm4::Vector3 vEigenU = rkRot.GetColumn(0); Wm4::Vector3 vEigenV = rkRot.GetColumn(1); @@ -534,16 +581,18 @@ void QuadraticFit::CalcEigenValues(double &dLambda1, double &dLambda2, double &d dLambda3 = rkDiag[2][2]; } -void QuadraticFit::CalcZValues( double x, double y, double &dZ1, double &dZ2 ) const +void QuadraticFit::CalcZValues(double x, double y, double& dZ1, double& dZ2) const { - assert( _bIsFitted ); + assert(_bIsFitted); - double dDisk = _fCoeff[3]*_fCoeff[3]+2*_fCoeff[3]*_fCoeff[8]*x+2*_fCoeff[3]*_fCoeff[9]*y+ - _fCoeff[8]*_fCoeff[8]*x*x+2*_fCoeff[8]*x*_fCoeff[9]*y+_fCoeff[9]*_fCoeff[9]*y*y- - 4*_fCoeff[6]*_fCoeff[0]-4*_fCoeff[6]*_fCoeff[1]*x-4*_fCoeff[6]*_fCoeff[2]*y- - 4*_fCoeff[6]*_fCoeff[7]*x*y-4*_fCoeff[6]*_fCoeff[4]*x*x-4*_fCoeff[6]*_fCoeff[5]*y*y; + double dDisk = _fCoeff[3] * _fCoeff[3] + 2 * _fCoeff[3] * _fCoeff[8] * x + + 2 * _fCoeff[3] * _fCoeff[9] * y + _fCoeff[8] * _fCoeff[8] * x * x + + 2 * _fCoeff[8] * x * _fCoeff[9] * y + _fCoeff[9] * _fCoeff[9] * y * y + - 4 * _fCoeff[6] * _fCoeff[0] - 4 * _fCoeff[6] * _fCoeff[1] * x + - 4 * _fCoeff[6] * _fCoeff[2] * y - 4 * _fCoeff[6] * _fCoeff[7] * x * y + - 4 * _fCoeff[6] * _fCoeff[4] * x * x - 4 * _fCoeff[6] * _fCoeff[5] * y * y; - if (fabs( _fCoeff[6] ) < 0.000005) { + if (fabs(_fCoeff[6]) < 0.000005) { dZ1 = double(FLOAT_MAX); dZ2 = double(FLOAT_MAX); return; @@ -554,19 +603,19 @@ void QuadraticFit::CalcZValues( double x, double y, double &dZ1, double &dZ2 ) c dZ2 = double(FLOAT_MAX); return; } - else - dDisk = sqrt( dDisk ); + else { + dDisk = sqrt(dDisk); + } - dZ1 = 0.5 * ( ( -_fCoeff[3] - _fCoeff[8]*x - _fCoeff[9]*y + dDisk ) / _fCoeff[6] ); - dZ2 = 0.5 * ( ( -_fCoeff[3] - _fCoeff[8]*x - _fCoeff[9]*y - dDisk ) / _fCoeff[6] ); + dZ1 = 0.5 * ((-_fCoeff[3] - _fCoeff[8] * x - _fCoeff[9] * y + dDisk) / _fCoeff[6]); + dZ2 = 0.5 * ((-_fCoeff[3] - _fCoeff[8] * x - _fCoeff[9] * y - dDisk) / _fCoeff[6]); } // ------------------------------------------------------------------------------- SurfaceFit::SurfaceFit() - : _fCoeff{} -{ -} + : _fCoeff {} +{} float SurfaceFit::Fit() { @@ -582,17 +631,23 @@ float SurfaceFit::Fit() return fResult; } -bool SurfaceFit::GetCurvatureInfo(double x, double y, double z, double &rfCurv0, double &rfCurv1, - Base::Vector3f &rkDir0, Base::Vector3f &rkDir1, double &dDistance ) +bool SurfaceFit::GetCurvatureInfo(double x, + double y, + double z, + double& rfCurv0, + double& rfCurv1, + Base::Vector3f& rkDir0, + Base::Vector3f& rkDir1, + double& dDistance) { bool bResult = false; if (_bIsFitted) { Wm4::Vector3 Dir0, Dir1; - FunctionContainer clFuncCont( _fCoeff ); - bResult = clFuncCont.CurvatureInfo( x, y, z, rfCurv0, rfCurv1, Dir0, Dir1, dDistance ); + FunctionContainer clFuncCont(_fCoeff); + bResult = clFuncCont.CurvatureInfo(x, y, z, rfCurv0, rfCurv1, Dir0, Dir1, dDistance); - dDistance = double(clFuncCont.GetGradient( x, y, z ).Length()); + dDistance = double(clFuncCont.GetGradient(x, y, z).Length()); rkDir0 = Base::convertTo(Dir0); rkDir1 = Base::convertTo(Dir1); } @@ -600,14 +655,14 @@ bool SurfaceFit::GetCurvatureInfo(double x, double y, double z, double &rfCurv0, return bResult; } -bool SurfaceFit::GetCurvatureInfo(double x, double y, double z, double &rfCurv0, double &rfCurv1) +bool SurfaceFit::GetCurvatureInfo(double x, double y, double z, double& rfCurv0, double& rfCurv1) { - assert( _bIsFitted ); + assert(_bIsFitted); bool bResult = false; if (_bIsFitted) { - FunctionContainer clFuncCont( _fCoeff ); - bResult = clFuncCont.CurvatureInfo( x, y, z, rfCurv0, rfCurv1 ); + FunctionContainer clFuncCont(_fCoeff); + bResult = clFuncCont.CurvatureInfo(x, y, z, rfCurv0, rfCurv1); } return bResult; @@ -615,13 +670,14 @@ bool SurfaceFit::GetCurvatureInfo(double x, double y, double z, double &rfCurv0, double SurfaceFit::PolynomFit() { - if (PlaneFit::Fit() >= FLOAT_MAX) + if (PlaneFit::Fit() >= FLOAT_MAX) { return double(FLOAT_MAX); + } Base::Vector3d bs = Base::convertTo(this->_vBase); Base::Vector3d ex = Base::convertTo(this->_vDirU); Base::Vector3d ey = Base::convertTo(this->_vDirV); - //Base::Vector3d ez = Base::convertTo(this->_vDirW); + // Base::Vector3d ez = Base::convertTo(this->_vDirW); // A*x = b // See also www.cs.jhu.edu/~misha/Fall05/10.23.05.pdf @@ -639,15 +695,16 @@ double SurfaceFit::PolynomFit() // <=> sum[(P*Vi)*Vi] = sum[Vi*zi] // <=> sum[(Vi*Vi^t)*P] = sum[Vi*zi] where (Vi*Vi^t) is a symmetric matrix // <=> sum[(Vi*Vi^t)]*P = sum[Vi*zi] - Eigen::Matrix A = Eigen::Matrix::Zero(); - Eigen::Matrix b = Eigen::Matrix::Zero(); - Eigen::Matrix x = Eigen::Matrix::Zero(); + Eigen::Matrix A = Eigen::Matrix::Zero(); + Eigen::Matrix b = Eigen::Matrix::Zero(); + Eigen::Matrix x = Eigen::Matrix::Zero(); std::vector transform; transform.reserve(_vPoints.size()); double dW2 = 0; - for (std::list::const_iterator it = _vPoints.begin(); it != _vPoints.end(); ++it) { + for (std::list::const_iterator it = _vPoints.begin(); it != _vPoints.end(); + ++it) { Base::Vector3d clPoint = Base::convertTo(*it); clPoint.TransformToCoordinateSystem(bs, ex, ey); transform.push_back(clPoint); @@ -655,69 +712,69 @@ double SurfaceFit::PolynomFit() double dV = clPoint.y; double dW = clPoint.z; - double dU2 = dU*dU; - double dV2 = dV*dV; - double dUV = dU*dV; + double dU2 = dU * dU; + double dV2 = dV * dV; + double dUV = dU * dV; - dW2 += dW*dW; + dW2 += dW * dW; - A(0,0) = A(0,0) + dU2*dU2; - A(0,1) = A(0,1) + dU2*dV2; - A(0,2) = A(0,2) + dU2*dUV; - A(0,3) = A(0,3) + dU2*dU ; - A(0,4) = A(0,4) + dU2*dV ; - A(0,5) = A(0,5) + dU2 ; - b(0) = b(0) + dU2*dW ; + A(0, 0) = A(0, 0) + dU2 * dU2; + A(0, 1) = A(0, 1) + dU2 * dV2; + A(0, 2) = A(0, 2) + dU2 * dUV; + A(0, 3) = A(0, 3) + dU2 * dU; + A(0, 4) = A(0, 4) + dU2 * dV; + A(0, 5) = A(0, 5) + dU2; + b(0) = b(0) + dU2 * dW; - A(1,1) = A(1,1) + dV2*dV2; - A(1,2) = A(1,2) + dV2*dUV; - A(1,3) = A(1,3) + dV2*dU ; - A(1,4) = A(1,4) + dV2*dV ; - A(1,5) = A(1,5) + dV2 ; - b(1) = b(1) + dV2*dW ; + A(1, 1) = A(1, 1) + dV2 * dV2; + A(1, 2) = A(1, 2) + dV2 * dUV; + A(1, 3) = A(1, 3) + dV2 * dU; + A(1, 4) = A(1, 4) + dV2 * dV; + A(1, 5) = A(1, 5) + dV2; + b(1) = b(1) + dV2 * dW; - A(2,2) = A(2,2) + dUV*dUV; - A(2,3) = A(2,3) + dUV*dU ; - A(2,4) = A(2,4) + dUV*dV ; - A(2,5) = A(2,5) + dUV ; - b(3) = b(3) + dUV*dW ; + A(2, 2) = A(2, 2) + dUV * dUV; + A(2, 3) = A(2, 3) + dUV * dU; + A(2, 4) = A(2, 4) + dUV * dV; + A(2, 5) = A(2, 5) + dUV; + b(3) = b(3) + dUV * dW; - A(3,3) = A(3,3) + dU *dU ; - A(3,4) = A(3,4) + dU *dV ; - A(3,5) = A(3,5) + dU ; - b(3) = b(3) + dU *dW ; + A(3, 3) = A(3, 3) + dU * dU; + A(3, 4) = A(3, 4) + dU * dV; + A(3, 5) = A(3, 5) + dU; + b(3) = b(3) + dU * dW; - A(4,4) = A(4,4) + dV *dV ; - A(4,5) = A(4,5) + dV ; - b(5) = b(5) + dV *dW ; + A(4, 4) = A(4, 4) + dV * dV; + A(4, 5) = A(4, 5) + dV; + b(5) = b(5) + dV * dW; - A(5,5) = A(5,5) + 1 ; - b(5) = b(5) + 1 *dW ; + A(5, 5) = A(5, 5) + 1; + b(5) = b(5) + 1 * dW; } // Mat is symmetric // - A(1,0) = A(0,1); - A(2,0) = A(0,2); - A(3,0) = A(0,3); - A(4,0) = A(0,4); - A(5,0) = A(0,5); + A(1, 0) = A(0, 1); + A(2, 0) = A(0, 2); + A(3, 0) = A(0, 3); + A(4, 0) = A(0, 4); + A(5, 0) = A(0, 5); - A(2,1) = A(1,2); - A(3,1) = A(1,3); - A(4,1) = A(1,4); - A(5,1) = A(1,5); + A(2, 1) = A(1, 2); + A(3, 1) = A(1, 3); + A(4, 1) = A(1, 4); + A(5, 1) = A(1, 5); - A(3,2) = A(2,3); - A(4,2) = A(2,4); - A(5,2) = A(2,5); + A(3, 2) = A(2, 3); + A(4, 2) = A(2, 4); + A(5, 2) = A(2, 5); - A(4,3) = A(3,4); - A(5,3) = A(3,5); + A(4, 3) = A(3, 4); + A(5, 3) = A(3, 5); - A(5,4) = A(4,5); + A(5, 4) = A(4, 5); - Eigen::HouseholderQR< Eigen::Matrix > qr(A); + Eigen::HouseholderQR> qr(A); x = qr.solve(b); // FunctionContainer gets an implicit function F(x,y,z) = 0 of this form @@ -748,28 +805,30 @@ double SurfaceFit::PolynomFit() _fCoeff[3] = -1.0; _fCoeff[4] = x(0); _fCoeff[5] = x(1); - _fCoeff[6] = 0.0; + _fCoeff[6] = 0.0; _fCoeff[7] = x(2); - _fCoeff[8] = 0.0; - _fCoeff[9] = 0.0; + _fCoeff[8] = 0.0; + _fCoeff[9] = 0.0; // Get S(P) = sum[(P*Vi)^2 - 2*(P*Vi)*zi + zi^2] double sigma = 0; FunctionContainer clFuncCont(_fCoeff); - for (const auto & it : transform) { + for (const auto& it : transform) { double u = it.x; double v = it.y; double z = clFuncCont.F(u, v, 0.0); - sigma += z*z; + sigma += z * z; } sigma += dW2 - 2 * x.dot(b); // This must be caused by some round-off errors. Theoretically it's impossible // that 'sigma' becomes negative. - if (sigma < 0) + if (sigma < 0) { sigma = 0; - if (!_vPoints.empty()) - sigma = sqrt(sigma/_vPoints.size()); + } + if (!_vPoints.empty()) { + sigma = sqrt(sigma / _vPoints.size()); + } _fLastResult = static_cast(sigma); return double(_fLastResult); @@ -786,7 +845,8 @@ double SurfaceFit::Value(double x, double y) const return z; } -void SurfaceFit::GetCoefficients(double& a,double& b,double& c,double& d,double& e,double& f) const +void SurfaceFit::GetCoefficients(double& a, double& b, double& c, double& d, double& e, double& f) + const { a = _fCoeff[4]; b = _fCoeff[5]; @@ -862,7 +922,8 @@ void SurfaceFit::Transform(std::vector& pts) const * f(x,y) = a*x*x + b*y*y + c*x*y + d*y + e*f + f * by getting the 3x3 control points. */ -std::vector SurfaceFit::toBezier(double umin, double umax, double vmin, double vmax) const +std::vector +SurfaceFit::toBezier(double umin, double umax, double vmin, double vmax) const { std::vector pts; pts.reserve(9); @@ -921,27 +982,28 @@ std::vector SurfaceFit::toBezier(double umin, double umax, doubl // ------------------------------------------------------------------------------- -namespace MeshCore { +namespace MeshCore +{ struct LMCylinderFunctor { Eigen::MatrixXd measuredValues; // Compute 'm' errors, one for each data point, for the given parameter values in 'x' - int operator()(const Eigen::VectorXd &xvec, Eigen::VectorXd &fvec) const + int operator()(const Eigen::VectorXd& xvec, Eigen::VectorXd& fvec) const { // 'xvec' has dimensions n x 1 // It contains the current estimates for the parameters. // 'fvec' has dimensions m x 1 // It will contain the error for each data point. - double aParam = xvec(0); // dir_x - double bParam = xvec(1); // dir_y - double cParam = xvec(2); // dir_z - double dParam = xvec(3); // cnt_x - double eParam = xvec(4); // cnt_y - double fParam = xvec(5); // cnt_z - double gParam = xvec(6); // radius + double aParam = xvec(0); // dir_x + double bParam = xvec(1); // dir_y + double cParam = xvec(2); // dir_z + double dParam = xvec(3); // cnt_x + double eParam = xvec(4); // cnt_y + double fParam = xvec(5); // cnt_z + double gParam = xvec(6); // radius // use distance functions (fvec(i)) for cylinders as defined in the paper: // Least-Squares Fitting Algorithms of the NIST Algorithm Testing System @@ -950,9 +1012,9 @@ struct LMCylinderFunctor double yValue = measuredValues(i, 1); double zValue = measuredValues(i, 2); - double a = aParam/(sqrt(aParam*aParam + bParam*bParam + cParam*cParam)); - double b = bParam/(sqrt(aParam*aParam + bParam*bParam + cParam*cParam)); - double c = cParam/(sqrt(aParam*aParam + bParam*bParam + cParam*cParam)); + double a = aParam / (sqrt(aParam * aParam + bParam * bParam + cParam * cParam)); + double b = bParam / (sqrt(aParam * aParam + bParam * bParam + cParam * cParam)); + double c = cParam / (sqrt(aParam * aParam + bParam * bParam + cParam * cParam)); double x = dParam; double y = eParam; double z = fParam; @@ -960,13 +1022,13 @@ struct LMCylinderFunctor double v = a * (zValue - z) - c * (xValue - x); double w = b * (xValue - x) - a * (yValue - y); - fvec(i) = sqrt(u*u + v*v + w*w) - gParam; + fvec(i) = sqrt(u * u + v * v + w * w) - gParam; } return 0; } // Compute the jacobian of the errors - int df(const Eigen::VectorXd &x, Eigen::MatrixXd &fjac) const + int df(const Eigen::VectorXd& x, Eigen::MatrixXd& fjac) const { // 'x' has dimensions n x 1 // It contains the current estimates for the parameters. @@ -1002,22 +1064,27 @@ struct LMCylinderFunctor int m; // Returns 'm', the number of values. - int values() const { return m; } + int values() const + { + return m; + } // The number of parameters, i.e. inputs. int n; // Returns 'n', the number of inputs. - int inputs() const { return n; } + int inputs() const + { + return n; + } }; -} +} // namespace MeshCore CylinderFit::CylinderFit() - : _vBase(0,0,0) - , _vAxis(0,0,1) -{ -} + : _vBase(0, 0, 0) + , _vAxis(0, 0, 1) +{} Base::Vector3f CylinderFit::GetInitialAxisFromNormals(const std::vector& n) const { @@ -1055,22 +1122,28 @@ Base::Vector3f CylinderFit::GetInitialAxisFromNormals(const std::vector eig(covMat); Eigen::Vector3d w = eig.eigenvectors().col(0); @@ -1088,16 +1161,20 @@ void CylinderFit::SetInitialValues(const Base::Vector3f& b, const Base::Vector3f float CylinderFit::Fit() { - if (CountPoints() < 7) + if (CountPoints() < 7) { return FLOAT_MAX; + } _bIsFitted = true; #if 1 // Do the cylinder fit MeshCoreFit::CylinderFit cylFit; cylFit.AddPoints(_vPoints); - if (_initialGuess) - cylFit.SetApproximations(_fRadius, Base::Vector3d(_vBase.x, _vBase.y, _vBase.z), Base::Vector3d(_vAxis.x, _vAxis.y, _vAxis.z)); + if (_initialGuess) { + cylFit.SetApproximations(_fRadius, + Base::Vector3d(_vBase.x, _vBase.y, _vBase.z), + Base::Vector3d(_vAxis.x, _vAxis.y, _vAxis.z)); + } float result = cylFit.Fit(); if (result < FLOAT_MAX) { @@ -1105,8 +1182,18 @@ float CylinderFit::Fit() Base::Vector3d dir = cylFit.GetAxis(); #if defined(FC_DEBUG) - Base::Console().Log("MeshCoreFit::Cylinder Fit: Base: (%0.4f, %0.4f, %0.4f), Axis: (%0.6f, %0.6f, %0.6f), Radius: %0.4f, Std Dev: %0.4f, Iterations: %d\n", - base.x, base.y, base.z, dir.x, dir.y, dir.z, cylFit.GetRadius(), cylFit.GetStdDeviation(), cylFit.GetNumIterations()); + Base::Console().Log( + "MeshCoreFit::Cylinder Fit: Base: (%0.4f, %0.4f, %0.4f), Axis: (%0.6f, %0.6f, " + "%0.6f), Radius: %0.4f, Std Dev: %0.4f, Iterations: %d\n", + base.x, + base.y, + base.z, + dir.x, + dir.y, + dir.z, + cylFit.GetRadius(), + cylFit.GetStdDeviation(), + cylFit.GetNumIterations()); #endif _vBase = Base::convertTo(base); _vAxis = Base::convertTo(dir); @@ -1127,13 +1214,13 @@ float CylinderFit::Fit() } Eigen::VectorXd x(n); - x(0) = 1.0; // initial value for dir_x - x(1) = 1.0; // initial value for dir_y - x(2) = 1.0; // initial value for dir_z - x(3) = 0.0; // initial value for cnt_x - x(4) = 0.0; // initial value for cnt_y - x(5) = 0.0; // initial value for cnt_z - x(6) = 0.0; // initial value for radius + x(0) = 1.0; // initial value for dir_x + x(1) = 1.0; // initial value for dir_y + x(2) = 1.0; // initial value for dir_z + x(3) = 0.0; // initial value for cnt_x + x(4) = 0.0; // initial value for cnt_y + x(5) = 0.0; // initial value for cnt_z + x(6) = 0.0; // initial value for radius // // Run the LM optimization @@ -1147,7 +1234,10 @@ float CylinderFit::Fit() Eigen::LevenbergMarquardt lm(functor); int status = lm.minimize(x); - Base::Console().Log("Cylinder fit: %d, iterations: %d, gradient norm: %f\n", status, lm.iter, lm.gnorm); + Base::Console().Log("Cylinder fit: %d, iterations: %d, gradient norm: %f\n", + status, + lm.iter, + lm.gnorm); _vAxis.x = x(0); _vAxis.y = x(1); @@ -1173,25 +1263,30 @@ float CylinderFit::GetRadius() const Base::Vector3f CylinderFit::GetBase() const { - if (_bIsFitted) + if (_bIsFitted) { return _vBase; - else + } + else { return Base::Vector3f(); + } } Base::Vector3f CylinderFit::GetAxis() const { - if (_bIsFitted) + if (_bIsFitted) { return _vAxis; - else + } + else { return Base::Vector3f(); + } } -float CylinderFit::GetDistanceToCylinder(const Base::Vector3f &rcPoint) const +float CylinderFit::GetDistanceToCylinder(const Base::Vector3f& rcPoint) const { float fResult = FLOAT_MAX; - if (_bIsFitted) + if (_bIsFitted) { fResult = rcPoint.DistanceToLine(_vBase, _vAxis) - _fRadius; + } return fResult; } @@ -1201,19 +1296,19 @@ float CylinderFit::GetStdDeviation() const // Variance: VAR=(N/N-1)*[(1/N)*SUM(Xi^2)-M^2] // Standard deviation: SD=SQRT(VAR) // Standard error of the mean: SE=SD/SQRT(N) - if (!_bIsFitted) + if (!_bIsFitted) { return FLOAT_MAX; + } - float fSumXi = 0.0f, fSumXi2 = 0.0f, - fMean = 0.0f, fDist = 0.0f; + float fSumXi = 0.0f, fSumXi2 = 0.0f, fMean = 0.0f, fDist = 0.0f; float ulPtCt = float(CountPoints()); - std::list< Base::Vector3f >::const_iterator cIt; + std::list::const_iterator cIt; for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) { - fDist = GetDistanceToCylinder( *cIt ); - fSumXi += fDist; - fSumXi2 += ( fDist * fDist ); + fDist = GetDistanceToCylinder(*cIt); + fSumXi += fDist; + fSumXi2 += (fDist * fDist); } fMean = (1.0f / ulPtCt) * fSumXi; @@ -1248,7 +1343,7 @@ void CylinderFit::ProjectToCylinder() Base::Vector3f cBase(GetBase()); Base::Vector3f cAxis(GetAxis()); - for (auto & cPnt : _vPoints) { + for (auto& cPnt : _vPoints) { if (cPnt.DistanceToLine(cBase, cAxis) > 0) { Base::Vector3f proj; cBase.ProjectToPlane(cPnt, cAxis, proj); @@ -1264,9 +1359,8 @@ void CylinderFit::ProjectToCylinder() float x = (float(rand()) / float(RAND_MAX)); float y = (float(rand()) / float(RAND_MAX)); float z = (float(rand()) / float(RAND_MAX)); - cMov.Move(x,y,z); - } - while (cMov.DistanceToLine(cBase, cAxis) == 0); + cMov.Move(x, y, z); + } while (cMov.DistanceToLine(cBase, cAxis) == 0); Base::Vector3f proj; cMov.ProjectToPlane(cPnt, cAxis, proj); @@ -1280,35 +1374,43 @@ void CylinderFit::ProjectToCylinder() // ----------------------------------------------------------------------------- SphereFit::SphereFit() - : _vCenter(0,0,0) -{ -} + : _vCenter(0, 0, 0) +{} float SphereFit::GetRadius() const { - if (_bIsFitted) + if (_bIsFitted) { return _fRadius; - else + } + else { return FLOAT_MAX; + } } Base::Vector3f SphereFit::GetCenter() const { - if (_bIsFitted) + if (_bIsFitted) { return _vCenter; - else + } + else { return Base::Vector3f(); + } } float SphereFit::Fit() { _bIsFitted = true; - if (CountPoints() < 4) + if (CountPoints() < 4) { return FLOAT_MAX; + } std::vector input; - std::transform(_vPoints.begin(), _vPoints.end(), std::back_inserter(input), - [](const Base::Vector3f& v) { return Wm4::Vector3d(v.x, v.y, v.z); }); + std::transform(_vPoints.begin(), + _vPoints.end(), + std::back_inserter(input), + [](const Base::Vector3f& v) { + return Wm4::Vector3d(v.x, v.y, v.z); + }); Wm4::Sphere3d sphere; Wm4::SphereFit3(input.size(), input.data(), 10, sphere, false); @@ -1319,8 +1421,13 @@ float SphereFit::Fit() _fLastResult = 0; #if defined(_DEBUG) - Base::Console().Message(" WildMagic Sphere Fit: Center: (%0.4f, %0.4f, %0.4f), Radius: %0.4f, Std Dev: %0.4f\n", - _vCenter.x, _vCenter.y, _vCenter.z, _fRadius, GetStdDeviation()); + Base::Console().Message(" WildMagic Sphere Fit: Center: (%0.4f, %0.4f, %0.4f), Radius: " + "%0.4f, Std Dev: %0.4f\n", + _vCenter.x, + _vCenter.y, + _vCenter.z, + _fRadius, + GetStdDeviation()); #endif MeshCoreFit::SphereFit sphereFit; @@ -1330,8 +1437,14 @@ float SphereFit::Fit() if (result < FLOAT_MAX) { Base::Vector3d center = sphereFit.GetCenter(); #if defined(_DEBUG) - Base::Console().Message("MeshCoreFit::Sphere Fit: Center: (%0.4f, %0.4f, %0.4f), Radius: %0.4f, Std Dev: %0.4f, Iterations: %d\n", - center.x, center.y, center.z, sphereFit.GetRadius(), sphereFit.GetStdDeviation(), sphereFit.GetNumIterations()); + Base::Console().Message("MeshCoreFit::Sphere Fit: Center: (%0.4f, %0.4f, %0.4f), Radius: " + "%0.4f, Std Dev: %0.4f, Iterations: %d\n", + center.x, + center.y, + center.z, + sphereFit.GetRadius(), + sphereFit.GetStdDeviation(), + sphereFit.GetNumIterations()); #endif _vCenter = Base::convertTo(center); _fRadius = (float)sphereFit.GetRadius(); @@ -1356,19 +1469,19 @@ float SphereFit::GetStdDeviation() const // Variance: VAR=(N/N-1)*[(1/N)*SUM(Xi^2)-M^2] // Standard deviation: SD=SQRT(VAR) // Standard error of the mean: SE=SD/SQRT(N) - if (!_bIsFitted) + if (!_bIsFitted) { return FLOAT_MAX; + } - float fSumXi = 0.0f, fSumXi2 = 0.0f, - fMean = 0.0f, fDist = 0.0f; + float fSumXi = 0.0f, fSumXi2 = 0.0f, fMean = 0.0f, fDist = 0.0f; float ulPtCt = float(CountPoints()); - std::list< Base::Vector3f >::const_iterator cIt; + std::list::const_iterator cIt; for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) { - fDist = GetDistanceToSphere( *cIt ); - fSumXi += fDist; - fSumXi2 += ( fDist * fDist ); + fDist = GetDistanceToSphere(*cIt); + fSumXi += fDist; + fSumXi2 += (fDist * fDist); } fMean = (1.0f / ulPtCt) * fSumXi; @@ -1377,22 +1490,20 @@ float SphereFit::GetStdDeviation() const void SphereFit::ProjectToSphere() { - for (auto & cPnt : _vPoints) { + for (auto& cPnt : _vPoints) { // Compute unit vector from sphere centre to point. // Because this vector is orthogonal to the sphere's surface at the // intersection point we can easily compute the projection point on the // closest surface point using the radius of the sphere Base::Vector3f diff = cPnt - _vCenter; double length = diff.Length(); - if (length == 0.0) - { - // Point is exactly at the sphere center, so it can be projected in any direction onto the sphere! - // So here just project in +Z direction + if (length == 0.0) { + // Point is exactly at the sphere center, so it can be projected in any direction onto + // the sphere! So here just project in +Z direction cPnt.z += _fRadius; } - else - { - diff /= length; // normalizing the vector + else { + diff /= length; // normalizing the vector cPnt = _vCenter + diff * _fRadius; } } @@ -1401,9 +1512,8 @@ void SphereFit::ProjectToSphere() // ------------------------------------------------------------------------------- PolynomialFit::PolynomialFit() - : _fCoeff{} -{ -} + : _fCoeff {} +{} float PolynomialFit::Fit() { @@ -1411,7 +1521,8 @@ float PolynomialFit::Fit() x.reserve(_vPoints.size()); y.reserve(_vPoints.size()); z.reserve(_vPoints.size()); - for (std::list::const_iterator it = _vPoints.begin(); it != _vPoints.end(); ++it) { + for (std::list::const_iterator it = _vPoints.begin(); it != _vPoints.end(); + ++it) { x.push_back(it->x); y.push_back(it->y); z.push_back(it->z); @@ -1419,8 +1530,9 @@ float PolynomialFit::Fit() try { float* coeff = Wm4::PolyFit3(_vPoints.size(), &(x[0]), &(y[0]), &(z[0]), 2, 2); - for (int i=0; i<9; i++) + for (int i = 0; i < 9; i++) { _fCoeff[i] = coeff[i]; + } } catch (const std::exception&) { return FLOAT_MAX; @@ -1431,15 +1543,8 @@ float PolynomialFit::Fit() float PolynomialFit::Value(float x, float y) const { - float fValue = - _fCoeff[0] + - _fCoeff[1] * x + - _fCoeff[2] * x * x + - _fCoeff[3] * y + - _fCoeff[4] * x * y + - _fCoeff[5] * x * x * y + - _fCoeff[6] * y * y + - _fCoeff[7] * x * y * y + - _fCoeff[8] * x * x * y * y; + float fValue = _fCoeff[0] + _fCoeff[1] * x + _fCoeff[2] * x * x + _fCoeff[3] * y + + _fCoeff[4] * x * y + _fCoeff[5] * x * x * y + _fCoeff[6] * y * y + _fCoeff[7] * x * y * y + + _fCoeff[8] * x * x * y * y; return fValue; } diff --git a/src/Mod/Mesh/App/Core/Approximation.h b/src/Mod/Mesh/App/Core/Approximation.h index a7e3ac60e3..3f15fe2fd1 100644 --- a/src/Mod/Mesh/App/Core/Approximation.h +++ b/src/Mod/Mesh/App/Core/Approximation.h @@ -25,7 +25,7 @@ #include #ifndef MESH_GLOBAL_H -# include +#include #endif #include #include @@ -43,56 +43,77 @@ namespace Wm4 /** * An implicit surface is defined by F(x,y,z) = 0. * This polynomial surface is actually defined as z = f(x,y) = ax^2 + by^2 + cx + dy + exy + g. - * To use Wm3 routines for implicit surfaces we can write the surface also as F(x,y,z) = f(x,y) - z = 0. + * To use Wm3 routines for implicit surfaces we can write the surface also as F(x,y,z) = f(x,y) - z + * = 0. * @author Werner Mayer */ -template -class PolynomialSurface : public ImplicitSurface +template +class PolynomialSurface: public ImplicitSurface { public: - explicit PolynomialSurface (const Real afCoeff[6]) - { for (int i=0; i<6; i++) m_afCoeff[i] = afCoeff[i]; } + explicit PolynomialSurface(const Real afCoeff[6]) + { + for (int i = 0; i < 6; i++) { + m_afCoeff[i] = afCoeff[i]; + } + } - // the function - Real F (const Vector3& rkP) const override - { - return ( m_afCoeff[0]*rkP.X()*rkP.X() + - m_afCoeff[1]*rkP.Y()*rkP.Y() + - m_afCoeff[2]*rkP.X() + - m_afCoeff[3]*rkP.Y() + - m_afCoeff[4]*rkP.X()*rkP.Y() + - m_afCoeff[5]-rkP.Z()) ; - } + // the function + Real F(const Vector3& rkP) const override + { + return (m_afCoeff[0] * rkP.X() * rkP.X() + m_afCoeff[1] * rkP.Y() * rkP.Y() + + m_afCoeff[2] * rkP.X() + m_afCoeff[3] * rkP.Y() + m_afCoeff[4] * rkP.X() * rkP.Y() + + m_afCoeff[5] - rkP.Z()); + } - // first-order partial derivatives - Real FX (const Vector3& rkP) const override - { return (Real)(2.0*m_afCoeff[0]*rkP.X() + m_afCoeff[2] + m_afCoeff[4]*rkP.Y()); } - Real FY (const Vector3& rkP) const override - { return (Real)(2.0*m_afCoeff[1]*rkP.Y() + m_afCoeff[3] + m_afCoeff[4]*rkP.X()); } - Real FZ (const Vector3& /*rkP*/) const override - { return (Real)-1.0; } + // first-order partial derivatives + Real FX(const Vector3& rkP) const override + { + return (Real)(2.0 * m_afCoeff[0] * rkP.X() + m_afCoeff[2] + m_afCoeff[4] * rkP.Y()); + } + Real FY(const Vector3& rkP) const override + { + return (Real)(2.0 * m_afCoeff[1] * rkP.Y() + m_afCoeff[3] + m_afCoeff[4] * rkP.X()); + } + Real FZ(const Vector3& /*rkP*/) const override + { + return (Real)-1.0; + } - // second-order partial derivatives - Real FXX (const Vector3& /*rkP*/) const override - { return (Real)(2.0*m_afCoeff[0]); } - Real FXY (const Vector3& /*rkP*/) const override - { return (Real)(m_afCoeff[4]); } - Real FXZ (const Vector3& /*rkP*/) const override - { return (Real)0.0; } - Real FYY (const Vector3& /*rkP*/) const override - { return (Real)(2.0*m_afCoeff[1]); } - Real FYZ (const Vector3& /*rkP*/) const override - { return (Real)0.0; } - Real FZZ (const Vector3& /*rkP*/) const override - { return (Real)0.0; } + // second-order partial derivatives + Real FXX(const Vector3& /*rkP*/) const override + { + return (Real)(2.0 * m_afCoeff[0]); + } + Real FXY(const Vector3& /*rkP*/) const override + { + return (Real)(m_afCoeff[4]); + } + Real FXZ(const Vector3& /*rkP*/) const override + { + return (Real)0.0; + } + Real FYY(const Vector3& /*rkP*/) const override + { + return (Real)(2.0 * m_afCoeff[1]); + } + Real FYZ(const Vector3& /*rkP*/) const override + { + return (Real)0.0; + } + Real FZZ(const Vector3& /*rkP*/) const override + { + return (Real)0.0; + } protected: - Real m_afCoeff[6]; + Real m_afCoeff[6]; }; -} +} // namespace Wm4 -namespace MeshCore { +namespace MeshCore +{ class MeshPointArray; /** @@ -112,27 +133,30 @@ public: /** * Add point for the fit algorithm. */ - void AddPoint(const Base::Vector3f &rcVector); + void AddPoint(const Base::Vector3f& rcVector); /** * Add points for the fit algorithm. */ - void AddPoints(const std::vector &rvPointVect); + void AddPoints(const std::vector& rvPointVect); /** * Add points for the fit algorithm. */ - void AddPoints(const std::set &rsPointSet); + void AddPoints(const std::set& rsPointSet); /** * Add points for the fit algorithm. */ - void AddPoints(const std::list &rsPointList); + void AddPoints(const std::list& rsPointList); /** * Add points for the fit algorithm. */ - void AddPoints(const MeshPointArray &points); + void AddPoints(const MeshPointArray& points); /** * Get all added points. */ - const std::list& GetPoints() const { return _vPoints; } + const std::list& GetPoints() const + { + return _vPoints; + } /** * Returns the center of gravity of the current added points. * @return Base::Vector3f @@ -166,14 +190,14 @@ protected: /** * Creates a vector of Wm4::Vector3 elements. */ - void GetMgcVectorArray( std::vector< Wm4::Vector3 >& rcPts ) const; + void GetMgcVectorArray(std::vector>& rcPts) const; protected: - //NOLINTBEGIN - std::list< Base::Vector3f > _vPoints; /**< Holds the points for the fit algorithm. */ - bool _bIsFitted{false}; /**< Flag, whether the fit has been called. */ - float _fLastResult{FLOAT_MAX}; /**< Stores the last result of the fit */ - //NOLINTEND + // NOLINTBEGIN + std::list _vPoints; /**< Holds the points for the fit algorithm. */ + bool _bIsFitted {false}; /**< Flag, whether the fit has been called. */ + float _fLastResult {FLOAT_MAX}; /**< Stores the last result of the fit */ + // NOLINTEND }; // ------------------------------------------------------------------------------- @@ -181,7 +205,7 @@ protected: /** * Approximation of a plane into a given set of points. */ -class MeshExport PlaneFit : public Approximation +class MeshExport PlaneFit: public Approximation { public: PlaneFit(); @@ -202,15 +226,15 @@ public: * Returns the distance from the point \a rcPoint to the fitted plane. If Fit() has not been * called FLOAT_MAX is returned. */ - float GetDistanceToPlane(const Base::Vector3f &rcPoint) const; + float GetDistanceToPlane(const Base::Vector3f& rcPoint) const; /** * Returns the standard deviation from the points to the fitted plane. If Fit() has not been * called FLOAT_MAX is returned. */ float GetStdDeviation() const; /** - * Returns the standard deviation from the points to the fitted plane with respect to the orientation - * of the plane's normal. If Fit() has not been called FLOAT_MAX is returned. + * Returns the standard deviation from the points to the fitted plane with respect to the + * orientation of the plane's normal. If Fit() has not been called FLOAT_MAX is returned. */ float GetSignedStdDeviation() const; /** @@ -235,12 +259,12 @@ public: Base::BoundBox3f GetBoundings() const; protected: - //NOLINTBEGIN + // NOLINTBEGIN Base::Vector3f _vBase; /**< Base vector of the plane. */ Base::Vector3f _vDirU; Base::Vector3f _vDirV; Base::Vector3f _vDirW; /**< Normal of the plane. */ - //NOLINTEND + // NOLINTEND }; // ------------------------------------------------------------------------------- @@ -254,7 +278,7 @@ protected: * Depending on the parameters (a,..,k) this surface defines a sphere, ellipsoid, cylinder, cone * and so on. */ -class MeshExport QuadraticFit : public Approximation +class MeshExport QuadraticFit: public Approximation { public: QuadraticFit() = default; @@ -276,7 +300,7 @@ public: */ float Fit() override; - void CalcZValues(double x, double y, double &dZ1, double &dZ2) const; + void CalcZValues(double x, double y, double& dZ1, double& dZ2) const; /** * Calculate the curvatures of the quadric at a given point. * @param x X-coordinate @@ -289,12 +313,16 @@ public: * @param dDistance * @return bool Success = true, otherwise false */ - bool GetCurvatureInfo(double x, double y, double z, - double &rfCurv0, double &rfCurv1, - Base::Vector3f &rkDir0, Base::Vector3f &rkDir1, double &dDistance); + bool GetCurvatureInfo(double x, + double y, + double z, + double& rfCurv0, + double& rfCurv1, + Base::Vector3f& rkDir0, + Base::Vector3f& rkDir1, + double& dDistance); - bool GetCurvatureInfo(double x, double y, double z, - double &rfCurv0, double &rfcurv1); + bool GetCurvatureInfo(double x, double y, double z, double& rfCurv0, double& rfcurv1); /** * Compute form matrix A and calculate Eigenvalues. * @param dLambda1 Eigenvalue 1 @@ -304,35 +332,44 @@ public: * @param clEV2 Eigenvector 2 * @param clEV3 Eigenvector 3 */ - void CalcEigenValues(double &dLambda1, double &dLambda2, double &dLambda3, - Base::Vector3f &clEV1, Base::Vector3f &clEV2, Base::Vector3f &clEV3) const; + void CalcEigenValues(double& dLambda1, + double& dLambda2, + double& dLambda3, + Base::Vector3f& clEV1, + Base::Vector3f& clEV2, + Base::Vector3f& clEV3) const; private: - double _fCoeff[ 10 ]{}; /**< Coefficients of the fit */ + double _fCoeff[10] {}; /**< Coefficients of the fit */ }; // ------------------------------------------------------------------------------- /** - * This is an 2.5D approach which first determines the bestfit plane of the point set (P_i = (x,y,z), i=1,...,n) - * to get a parametrisation of the points afterwards. The coordinates of the points with respect to the local - * coordinate system of the plane are determined and then a quadratic polynomial function of the form: - * w = f(u,v) = a*u^2 + b*v^2 + c*u*v + d*u + e*v + f - * is determined. - * This approach was developed as an alternative for the 3D approach with quadrics because - * the latter suffers from strange artifacts in planar areas. + * This is an 2.5D approach which first determines the bestfit plane of the point set (P_i = + * (x,y,z), i=1,...,n) to get a parametrisation of the points afterwards. The coordinates of the + * points with respect to the local coordinate system of the plane are determined and then a + * quadratic polynomial function of the form: w = f(u,v) = a*u^2 + b*v^2 + c*u*v + d*u + e*v + f is + * determined. This approach was developed as an alternative for the 3D approach with quadrics + * because the latter suffers from strange artifacts in planar areas. */ -class MeshExport SurfaceFit : public PlaneFit +class MeshExport SurfaceFit: public PlaneFit { public: SurfaceFit(); - bool GetCurvatureInfo(double x, double y, double z, double &rfCurv0, double &rfCurv1, - Base::Vector3f &rkDir0, Base::Vector3f &rkDir1, double &dDistance); - bool GetCurvatureInfo(double x, double y, double z, double &rfCurv0, double &rfcurv1); + bool GetCurvatureInfo(double x, + double y, + double z, + double& rfCurv0, + double& rfCurv1, + Base::Vector3f& rkDir0, + Base::Vector3f& rkDir1, + double& dDistance); + bool GetCurvatureInfo(double x, double y, double z, double& rfCurv0, double& rfcurv1); float Fit() override; double Value(double x, double y) const; - void GetCoefficients(double& a,double& b,double& c,double& d,double& e,double& f) const; + void GetCoefficients(double& a, double& b, double& c, double& d, double& e, double& f) const; /** * @brief Transform * Transforms points from the local coordinate system to the world coordinate system @@ -347,11 +384,12 @@ public: * @param vmax Parameter range * @return control points of the Bezier surface */ - std::vector toBezier(double umin=0.0, double umax=1.0, double vmin=0.0, double vmax=1.0) const; + std::vector + toBezier(double umin = 0.0, double umax = 1.0, double vmin = 0.0, double vmax = 1.0) const; protected: double PolynomFit(); - double _fCoeff[ 10 ]; /**< Ziel der Koeffizienten aus dem Fit */ + double _fCoeff[10]; /**< Ziel der Koeffizienten aus dem Fit */ }; // ------------------------------------------------------------------------------- @@ -359,7 +397,7 @@ protected: /** * Approximation of a cylinder into a given set of points. */ -class MeshExport CylinderFit : public Approximation +class MeshExport CylinderFit: public Approximation { public: CylinderFit(); @@ -383,7 +421,7 @@ public: * Returns the distance from the point \a rcPoint to the fitted cylinder. If Fit() has not been * called FLOAT_MAX is returned. */ - float GetDistanceToCylinder(const Base::Vector3f &rcPoint) const; + float GetDistanceToCylinder(const Base::Vector3f& rcPoint) const; /** * Returns the standard deviation from the points to the fitted cylinder. If Fit() has not been * called FLOAT_MAX is returned. @@ -402,8 +440,8 @@ public: protected: Base::Vector3f _vBase; /**< Base vector of the cylinder. */ Base::Vector3f _vAxis; /**< Axis of the cylinder. */ - float _fRadius{0}; /**< Radius of the cylinder. */ - bool _initialGuess{false}; + float _fRadius {0}; /**< Radius of the cylinder. */ + bool _initialGuess {false}; }; // ------------------------------------------------------------------------------- @@ -411,7 +449,7 @@ protected: /** * Approximation of a sphere into a given set of points. */ -class MeshExport SphereFit : public Approximation +class MeshExport SphereFit: public Approximation { public: SphereFit(); @@ -425,7 +463,7 @@ public: * Returns the distance from the point \a rcPoint to the fitted sphere. If Fit() has not been * called FLOAT_MAX is returned. */ - float GetDistanceToSphere(const Base::Vector3f &rcPoint) const; + float GetDistanceToSphere(const Base::Vector3f& rcPoint) const; /** * Returns the standard deviation from the points to the fitted sphere. If Fit() has not been * called FLOAT_MAX is returned. @@ -438,7 +476,7 @@ public: protected: Base::Vector3f _vCenter; /**< Center of the sphere. */ - float _fRadius{0}; /**< Radius of the cylinder. */ + float _fRadius {0}; /**< Radius of the cylinder. */ }; // ------------------------------------------------------------------------------- @@ -454,38 +492,45 @@ public: /** * WildMagic library uses function with this interface */ - using Function = double (*)(double,double,double); + using Function = double (*)(double, double, double); /** * The constructor expects an array of quadric coefficients. * @param pKoef Pointer to the quadric coefficients * (double [10]) */ - explicit FunctionContainer(const double *pKoef) + explicit FunctionContainer(const double* pKoef) { - Assign( pKoef ); - pImplSurf = new Wm4::QuadricSurface( dKoeff ); + Assign(pKoef); + pImplSurf = new Wm4::QuadricSurface(dKoeff); } /** * Apply quadric coefficients * @param pKoef Pointer to the quadric coefficients * (double [10]) */ - void Assign( const double *pKoef ) + void Assign(const double* pKoef) { - for (long ct=0; ct < 10; ct++) - dKoeff[ ct ] = pKoef[ ct ]; + for (long ct = 0; ct < 10; ct++) { + dKoeff[ct] = pKoef[ct]; + } } /** * Destructor. Deletes the ImpicitSurface instance * of the WildMagic library */ - ~FunctionContainer(){ delete pImplSurf; } + ~FunctionContainer() + { + delete pImplSurf; + } /** * Access to the quadric coefficients * @param idx Index to coefficient * @return double& coefficient */ - double& operator[](int idx){ return dKoeff[ idx ]; } + double& operator[](int idx) + { + return dKoeff[idx]; + } /** * Redirector to a method of the WildMagic library. Determines * the principal curvatures and their directions at the given point. @@ -499,49 +544,66 @@ public: * @param dDistance Gives distances from the point to the quadric. * @return bool Success = true, otherwise false */ - bool CurvatureInfo(double x, double y, double z, - double &rfCurv0, double &rfCurv1, - Wm4::Vector3 &rkDir0, Wm4::Vector3 &rkDir1, double &dDistance) + bool CurvatureInfo(double x, + double y, + double z, + double& rfCurv0, + double& rfCurv1, + Wm4::Vector3& rkDir0, + Wm4::Vector3& rkDir1, + double& dDistance) { (void)dDistance; - return pImplSurf->ComputePrincipalCurvatureInfo( Wm4::Vector3(x, y, z),rfCurv0, rfCurv1, rkDir0, rkDir1 ); + return pImplSurf->ComputePrincipalCurvatureInfo(Wm4::Vector3(x, y, z), + rfCurv0, + rfCurv1, + rkDir0, + rkDir1); } - Base::Vector3f GetGradient( double x, double y, double z ) const + Base::Vector3f GetGradient(double x, double y, double z) const { - Wm4::Vector3 grad = pImplSurf->GetGradient( Wm4::Vector3(x, y, z) ); + Wm4::Vector3 grad = pImplSurf->GetGradient(Wm4::Vector3(x, y, z)); return Base::Vector3f(static_cast(grad.X()), static_cast(grad.Y()), static_cast(grad.Z())); } - Base::Matrix4D GetHessian( double x, double y, double z ) const + Base::Matrix4D GetHessian(double x, double y, double z) const { - Wm4::Matrix3 hess = pImplSurf->GetHessian( Wm4::Vector3(x, y, z) ); - Base::Matrix4D cMat; cMat.setToUnity(); - cMat[0][0] = hess[0][0]; cMat[0][1] = hess[0][1]; cMat[0][2] = hess[0][2]; - cMat[1][0] = hess[1][0]; cMat[1][1] = hess[1][1]; cMat[1][2] = hess[1][2]; - cMat[2][0] = hess[2][0]; cMat[2][1] = hess[2][1]; cMat[2][2] = hess[2][2]; + Wm4::Matrix3 hess = pImplSurf->GetHessian(Wm4::Vector3(x, y, z)); + Base::Matrix4D cMat; + cMat.setToUnity(); + cMat[0][0] = hess[0][0]; + cMat[0][1] = hess[0][1]; + cMat[0][2] = hess[0][2]; + cMat[1][0] = hess[1][0]; + cMat[1][1] = hess[1][1]; + cMat[1][2] = hess[1][2]; + cMat[2][0] = hess[2][0]; + cMat[2][1] = hess[2][1]; + cMat[2][2] = hess[2][2]; return cMat; } - bool CurvatureInfo(double x, double y, double z, - double &rfCurv0, double &rfCurv1) + bool CurvatureInfo(double x, double y, double z, double& rfCurv0, double& rfCurv1) { - double dQuot = Fz(x,y,z); - double zx = - ( Fx(x,y,z) / dQuot ); - double zy = - ( Fy(x,y,z) / dQuot ); + double dQuot = Fz(x, y, z); + double zx = -(Fx(x, y, z) / dQuot); + double zy = -(Fy(x, y, z) / dQuot); - double zxx = - ( 2.0 * ( dKoeff[5] + dKoeff[6] * zx * zx + dKoeff[8] * zx ) ) / dQuot; - double zyy = - ( 2.0 * ( dKoeff[5] + dKoeff[6] * zy * zy + dKoeff[9] * zy ) ) / dQuot; - double zxy = - ( dKoeff[6] * zx * zy + dKoeff[7] + dKoeff[8] * zy + dKoeff[9] * zx ) / dQuot; + double zxx = -(2.0 * (dKoeff[5] + dKoeff[6] * zx * zx + dKoeff[8] * zx)) / dQuot; + double zyy = -(2.0 * (dKoeff[5] + dKoeff[6] * zy * zy + dKoeff[9] * zy)) / dQuot; + double zxy = -(dKoeff[6] * zx * zy + dKoeff[7] + dKoeff[8] * zy + dKoeff[9] * zx) / dQuot; - double dNen = 1 + zx*zx + zy*zy; - double dNenSqrt = sqrt( dNen ); - double K = ( zxx * zyy - zxy * zxy ) / ( dNen * dNen ); - double H = 0.5 * ( ( 1.0+zx*zx - 2*zx*zy*zxy + (1.0+zy*zy)*zxx ) / ( dNenSqrt * dNenSqrt * dNenSqrt ) ) ; + double dNen = 1 + zx * zx + zy * zy; + double dNenSqrt = sqrt(dNen); + double K = (zxx * zyy - zxy * zxy) / (dNen * dNen); + double H = 0.5 + * ((1.0 + zx * zx - 2 * zx * zy * zxy + (1.0 + zy * zy) * zxx) + / (dNenSqrt * dNenSqrt * dNenSqrt)); - double dDiscr = sqrt(fabs(H*H-K)); + double dDiscr = sqrt(fabs(H * H - K)); rfCurv0 = H - dDiscr; rfCurv1 = H + dDiscr; @@ -549,62 +611,74 @@ public: } //+++++++++ Quadric +++++++++++++++++++++++++++++++++++++++ - double F ( double x, double y, double z ) + double F(double x, double y, double z) { - return (dKoeff[0] + dKoeff[1]*x + dKoeff[2]*y + dKoeff[3]*z + - dKoeff[4]*x*x + dKoeff[5]*y*y + dKoeff[6]*z*z + - dKoeff[7]*x*y + dKoeff[8]*x*z + dKoeff[9]*y*z); + return (dKoeff[0] + dKoeff[1] * x + dKoeff[2] * y + dKoeff[3] * z + dKoeff[4] * x * x + + dKoeff[5] * y * y + dKoeff[6] * z * z + dKoeff[7] * x * y + dKoeff[8] * x * z + + dKoeff[9] * y * z); } //+++++++++ 1. derivations ++++++++++++++++++++++++++++++++ - double Fx ( double x, double y, double z ) + double Fx(double x, double y, double z) { - return( dKoeff[1] + 2.0*dKoeff[4]*x + dKoeff[7]*y + dKoeff[8]*z ); + return (dKoeff[1] + 2.0 * dKoeff[4] * x + dKoeff[7] * y + dKoeff[8] * z); } - double Fy ( double x, double y, double z ) + double Fy(double x, double y, double z) { - return( dKoeff[2] + 2.0*dKoeff[5]*y + dKoeff[7]*x + dKoeff[9]*z ); + return (dKoeff[2] + 2.0 * dKoeff[5] * y + dKoeff[7] * x + dKoeff[9] * z); } - double Fz ( double x, double y, double z ) + double Fz(double x, double y, double z) { - return( dKoeff[3] + 2.0*dKoeff[6]*z + dKoeff[8]*x + dKoeff[9]*y ); + return (dKoeff[3] + 2.0 * dKoeff[6] * z + dKoeff[8] * x + dKoeff[9] * y); } //+++++++++ 2. derivations ++++++++++++++++++++++++++++++++ - double Fxx( double x, double y, double z ) + double Fxx(double x, double y, double z) { - (void)x; (void)y; (void)z; - return( 2.0*dKoeff[4] ); + (void)x; + (void)y; + (void)z; + return (2.0 * dKoeff[4]); } - double Fxy( double x, double y, double z ) + double Fxy(double x, double y, double z) { - (void)x; (void)y; (void)z; - return( dKoeff[7] ); + (void)x; + (void)y; + (void)z; + return (dKoeff[7]); } - double Fxz( double x, double y, double z ) + double Fxz(double x, double y, double z) { - (void)x; (void)y; (void)z; - return( dKoeff[8] ); + (void)x; + (void)y; + (void)z; + return (dKoeff[8]); } - double Fyy( double x, double y, double z ) + double Fyy(double x, double y, double z) { - (void)x; (void)y; (void)z; - return( 2.0*dKoeff[5] ); + (void)x; + (void)y; + (void)z; + return (2.0 * dKoeff[5]); } - double Fyz( double x, double y, double z ) + double Fyz(double x, double y, double z) { - (void)x; (void)y; (void)z; - return( dKoeff[9] ); + (void)x; + (void)y; + (void)z; + return (dKoeff[9]); } - double Fzz( double x, double y, double z ) + double Fzz(double x, double y, double z) { - (void)x; (void)y; (void)z; - return( 2.0*dKoeff[6] ); + (void)x; + (void)y; + (void)z; + return (2.0 * dKoeff[6]); } protected: - double dKoeff[ 10 ]; /**< Coefficients of quadric */ - Wm4::ImplicitSurface *pImplSurf; /**< Access to the WildMagic library */ + double dKoeff[10]; /**< Coefficients of quadric */ + Wm4::ImplicitSurface* pImplSurf; /**< Access to the WildMagic library */ private: /** @@ -613,7 +687,7 @@ private: FunctionContainer() = default; }; -class MeshExport PolynomialFit : public Approximation +class MeshExport PolynomialFit: public Approximation { public: PolynomialFit(); @@ -625,6 +699,6 @@ protected: float _fCoeff[9]; }; -} // namespace MeshCore +} // namespace MeshCore -#endif // MESH_APPROXIMATION_H +#endif // MESH_APPROXIMATION_H diff --git a/src/Mod/Mesh/App/Core/Builder.cpp b/src/Mod/Mesh/App/Core/Builder.cpp index 4f7cc42165..f2e312c638 100644 --- a/src/Mod/Mesh/App/Core/Builder.cpp +++ b/src/Mod/Mesh/App/Core/Builder.cpp @@ -23,7 +23,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include @@ -38,13 +38,12 @@ using namespace MeshCore; -MeshBuilder::MeshBuilder (MeshKernel& kernel) +MeshBuilder::MeshBuilder(MeshKernel& kernel) : _meshKernel(kernel) - , _fSaveTolerance{MeshDefinitions::_fMinPointDistanceD1} -{ -} + , _fSaveTolerance {MeshDefinitions::_fMinPointDistanceD1} +{} -MeshBuilder::~MeshBuilder () +MeshBuilder::~MeshBuilder() { MeshDefinitions::_fMinPointDistanceD1 = _fSaveTolerance; delete this->_seq; @@ -55,74 +54,85 @@ void MeshBuilder::SetTolerance(float fTol) MeshDefinitions::_fMinPointDistanceD1 = fTol; } -void MeshBuilder::Initialize (size_t ctFacets, bool deletion) +void MeshBuilder::Initialize(size_t ctFacets, bool deletion) { - if (deletion) - { + if (deletion) { // Clear the mesh structure and free all memory _meshKernel.Clear(); - // Allocate new memory that is needed later on. If AddFacet() gets called exactly ctFacets times there is no wastage of memory - // otherwise the vector reallocates ~50% of its future memory usage. - // Note: A feature of the std::vector implementation is that it can hold more memory (capacity) than it actually needs (size). - // This usually happens if its elements are added without specifying its final size. Later on it's a bit tricky to free the wasted - // memory. So we're strived to avoid the wastage of memory. + // Allocate new memory that is needed later on. If AddFacet() gets called exactly ctFacets + // times there is no wastage of memory otherwise the vector reallocates ~50% of its future + // memory usage. Note: A feature of the std::vector implementation is that it can hold more + // memory (capacity) than it actually needs (size). + // This usually happens if its elements are added without specifying its final size. + // Later on it's a bit tricky to free the wasted memory. So we're strived to avoid the + // wastage of memory. _meshKernel._aclFacetArray.reserve(ctFacets); - // Usually the number of vertices is the half of the number of facets. So we reserve this memory with 10% surcharge - // To save memory we hold an array with iterators that point to the right vertex (insertion order) in the set, instead of - // holding the vertex array twice. + // Usually the number of vertices is the half of the number of facets. So we reserve this + // memory with 10% surcharge To save memory we hold an array with iterators that point to + // the right vertex (insertion order) in the set, instead of holding the vertex array twice. size_t ctPoints = ctFacets / 2; - _pointsIterator.reserve(static_cast(float(ctPoints)*1.10f)); + _pointsIterator.reserve(static_cast(float(ctPoints) * 1.10f)); _ptIdx = 0; } - else - { - for (const auto & it1 : _meshKernel._aclPointArray) - { + else { + for (const auto& it1 : _meshKernel._aclPointArray) { MeshPointIterator pit = _points.insert(it1); _pointsIterator.push_back(pit); } _ptIdx = _points.size(); - // As we have a copy of our vertices in the set we must clear them from our array now But we can keep its - // memory as we reuse it later on anyway. + // As we have a copy of our vertices in the set we must clear them from our array now But + // we can keep its memory as we reuse it later on anyway. _meshKernel._aclPointArray.clear(); // additional memory - size_t newCtFacets = _meshKernel._aclFacetArray.size()+ctFacets; + size_t newCtFacets = _meshKernel._aclFacetArray.size() + ctFacets; _meshKernel._aclFacetArray.reserve(newCtFacets); size_t ctPoints = newCtFacets / 2; - _pointsIterator.reserve(static_cast(float(ctPoints)*1.10f)); + _pointsIterator.reserve(static_cast(float(ctPoints) * 1.10f)); } this->_seq = new Base::SequencerLauncher("create mesh structure...", ctFacets * 2); } -void MeshBuilder::AddFacet (const MeshGeomFacet& facet, bool takeFlag, bool takeProperty) +void MeshBuilder::AddFacet(const MeshGeomFacet& facet, bool takeFlag, bool takeProperty) { unsigned char flag = 0; unsigned long prop = 0; - if (takeFlag) + if (takeFlag) { flag = facet._ucFlag; - if (takeProperty) + } + if (takeProperty) { prop = facet._ulProp; + } - AddFacet(facet._aclPoints[0], facet._aclPoints[1], facet._aclPoints[2], facet.GetNormal(), flag, prop); + AddFacet(facet._aclPoints[0], + facet._aclPoints[1], + facet._aclPoints[2], + facet.GetNormal(), + flag, + prop); } -void MeshBuilder::AddFacet (const Base::Vector3f& pt1, const Base::Vector3f& pt2, const Base::Vector3f& pt3, const Base::Vector3f& normal, unsigned char flag, unsigned long prop) +void MeshBuilder::AddFacet(const Base::Vector3f& pt1, + const Base::Vector3f& pt2, + const Base::Vector3f& pt3, + const Base::Vector3f& normal, + unsigned char flag, + unsigned long prop) { - Base::Vector3f facetPoints[4] = { pt1, pt2, pt3, normal }; + Base::Vector3f facetPoints[4] = {pt1, pt2, pt3, normal}; AddFacet(facetPoints, flag, prop); } -void MeshBuilder::AddFacet (Base::Vector3f* facetPoints, unsigned char flag, unsigned long prop) +void MeshBuilder::AddFacet(Base::Vector3f* facetPoints, unsigned char flag, unsigned long prop) { - this->_seq->next(true); // allow to cancel + this->_seq->next(true); // allow to cancel // adjust circulation direction - if ((((facetPoints[1] - facetPoints[0]) % (facetPoints[2] - facetPoints[0])) * facetPoints[3]) < 0.0f) - { + if ((((facetPoints[1] - facetPoints[0]) % (facetPoints[2] - facetPoints[0])) * facetPoints[3]) + < 0.0f) { std::swap(facetPoints[1], facetPoints[2]); } @@ -131,65 +141,65 @@ void MeshBuilder::AddFacet (Base::Vector3f* facetPoints, unsigned char flag, uns mf._ulProp = prop; int i = 0; - for (i = 0; i < 3; i++) - { + for (i = 0; i < 3; i++) { MeshPoint pt(facetPoints[i]); std::set::iterator p = _points.find(pt); - if (p == _points.end()) - { + if (p == _points.end()) { mf._aulPoints[i] = _ptIdx; pt._ulProp = _ptIdx++; // keep an iterator to the right vertex MeshPointIterator it = _points.insert(pt); _pointsIterator.push_back(it); } - else + else { mf._aulPoints[i] = p->_ulProp; + } } // check for degenerated facet (one edge has length 0) - if ((mf._aulPoints[0] == mf._aulPoints[1]) || (mf._aulPoints[0] == mf._aulPoints[2]) || (mf._aulPoints[1] == mf._aulPoints[2])) + if ((mf._aulPoints[0] == mf._aulPoints[1]) || (mf._aulPoints[0] == mf._aulPoints[2]) + || (mf._aulPoints[1] == mf._aulPoints[2])) { return; + } _meshKernel._aclFacetArray.push_back(mf); } -void MeshBuilder::SetNeighbourhood () +void MeshBuilder::SetNeighbourhood() { std::set edges; FacetIndex facetIdx = 0; - for (auto & mf : _meshKernel._aclFacetArray) - { - this->_seq->next(true); // allow to cancel - for (int i = 0; i < 3; i++) - { - Edge edge(mf._aulPoints[i], mf._aulPoints[(i+1)%3], facetIdx); + for (auto& mf : _meshKernel._aclFacetArray) { + this->_seq->next(true); // allow to cancel + for (int i = 0; i < 3; i++) { + Edge edge(mf._aulPoints[i], mf._aulPoints[(i + 1) % 3], facetIdx); std::set::iterator e = edges.find(edge); - if (e != edges.end()) - { // edge exists, set neighbourhood + if (e != edges.end()) { // edge exists, set neighbourhood MeshFacet& mf1 = _meshKernel._aclFacetArray[e->facetIdx]; - if (mf1._aulPoints[0] == edge.pt1) - { - if (mf1._aulPoints[1] == edge.pt2) + if (mf1._aulPoints[0] == edge.pt1) { + if (mf1._aulPoints[1] == edge.pt2) { mf1._aulNeighbours[0] = facetIdx; - else + } + else { mf1._aulNeighbours[2] = facetIdx; + } } - else if (mf1._aulPoints[0] == edge.pt2) - { - if (mf1._aulPoints[1] == edge.pt1) + else if (mf1._aulPoints[0] == edge.pt2) { + if (mf1._aulPoints[1] == edge.pt1) { mf1._aulNeighbours[0] = facetIdx; - else + } + else { mf1._aulNeighbours[2] = facetIdx; + } } - else + else { mf1._aulNeighbours[1] = facetIdx; + } mf._aulNeighbours[i] = e->facetIdx; } - else - { // new edge + else { // new edge edges.insert(edge); } } @@ -201,54 +211,62 @@ void MeshBuilder::SetNeighbourhood () void MeshBuilder::RemoveUnreferencedPoints() { _meshKernel._aclPointArray.SetFlag(MeshPoint::INVALID); - for (const auto & it : _meshKernel._aclFacetArray) - { - for (PointIndex point : it._aulPoints) + for (const auto& it : _meshKernel._aclFacetArray) { + for (PointIndex point : it._aulPoints) { _meshKernel._aclPointArray[point].ResetInvalid(); + } } unsigned long uValidPts = std::count_if(_meshKernel._aclPointArray.begin(), _meshKernel._aclPointArray.end(), - [](const MeshPoint& p) { return p.IsValid(); }); - if ( uValidPts < _meshKernel.CountPoints() ) + [](const MeshPoint& p) { + return p.IsValid(); + }); + if (uValidPts < _meshKernel.CountPoints()) { _meshKernel.RemoveInvalids(); + } } -void MeshBuilder::Finish (bool freeMemory) +void MeshBuilder::Finish(bool freeMemory) { - // now we can resize the vertex array to the exact size and copy the vertices with their correct positions in the array - PointIndex i=0; + // now we can resize the vertex array to the exact size and copy the vertices with their correct + // positions in the array + PointIndex i = 0; _meshKernel._aclPointArray.resize(_pointsIterator.size()); - for (const auto & it : _pointsIterator) + for (const auto& it : _pointsIterator) { _meshKernel._aclPointArray[i++] = *(it.first); + } // free all memory of the internal structures // Note: this scope is needed to free memory immediately #if defined(_MSC_VER) && defined(_DEBUG) // Just do nothing here as it may take a long time when running the debugger #else - { std::vector().swap(_pointsIterator); } + { + std::vector().swap(_pointsIterator); + } #endif _points.clear(); SetNeighbourhood(); RemoveUnreferencedPoints(); - // if AddFacet() has been called more often (or even less) as specified in Initialize() we have a wastage of memory - if ( freeMemory ) - { + // if AddFacet() has been called more often (or even less) as specified in Initialize() we have + // a wastage of memory + if (freeMemory) { size_t cap = _meshKernel._aclFacetArray.capacity(); size_t siz = _meshKernel._aclFacetArray.size(); // wastage of more than 5% - if ( cap > siz+siz/20 ) - { + if (cap > siz + siz / 20) { try { - FacetIndex i=0; + FacetIndex i = 0; MeshFacetArray faces(siz); - for (const auto & it : _meshKernel._aclFacetArray) + for (const auto& it : _meshKernel._aclFacetArray) { faces[i++] = it; + } _meshKernel._aclFacetArray.swap(faces); - } catch ( const Base::MemoryException&) { + } + catch (const Base::MemoryException&) { // sorry, we cannot reduce the memory } } @@ -259,11 +277,22 @@ void MeshBuilder::Finish (bool freeMemory) // ---------------------------------------------------------------------------- -struct MeshFastBuilder::Private { +struct MeshFastBuilder::Private +{ struct Vertex { - Vertex() : x(0), y(0), z(0), i(0) {} - Vertex(float x, float y, float z) : x(x), y(y), z(z), i(0) {} + Vertex() + : x(0) + , y(0) + , z(0) + , i(0) + {} + Vertex(float x, float y, float z) + : x(x) + , y(y) + , z(z) + , i(0) + {} float x, y, z; size_type i; @@ -274,14 +303,18 @@ struct MeshFastBuilder::Private { } bool operator<(const Vertex& rhs) const { - if (x != rhs.x) + if (x != rhs.x) { return x < rhs.x; - else if (y != rhs.y) + } + else if (y != rhs.y) { return y < rhs.y; - else if (z != rhs.z) + } + else if (z != rhs.z) { return z < rhs.z; - else + } + else { return false; + } } }; @@ -289,24 +322,25 @@ struct MeshFastBuilder::Private { QVector verts; }; -MeshFastBuilder::MeshFastBuilder(MeshKernel &rclM) : _meshKernel(rclM), p(new Private) -{ -} +MeshFastBuilder::MeshFastBuilder(MeshKernel& rclM) + : _meshKernel(rclM) + , p(new Private) +{} MeshFastBuilder::~MeshFastBuilder() { delete p; } -void MeshFastBuilder::Initialize (size_type ctFacets) +void MeshFastBuilder::Initialize(size_type ctFacets) { p->verts.reserve(ctFacets * 3); } -void MeshFastBuilder::AddFacet (const Base::Vector3f* facetPoints) +void MeshFastBuilder::AddFacet(const Base::Vector3f* facetPoints) { Private::Vertex v; - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { v.x = facetPoints[i].x; v.y = facetPoints[i].y; v.z = facetPoints[i].z; @@ -314,7 +348,7 @@ void MeshFastBuilder::AddFacet (const Base::Vector3f* facetPoints) } } -void MeshFastBuilder::AddFacet (const MeshGeomFacet& facetPoints) +void MeshFastBuilder::AddFacet(const MeshGeomFacet& facetPoints) { Private::Vertex v; for (const auto& pnt : facetPoints._aclPoints) { @@ -325,16 +359,16 @@ void MeshFastBuilder::AddFacet (const MeshGeomFacet& facetPoints) } } -void MeshFastBuilder::Finish () +void MeshFastBuilder::Finish() { using size_type = QVector::size_type; QVector& verts = p->verts; size_type ulCtPts = verts.size(); - for (size_type i=0; i < ulCtPts; ++i) { + for (size_type i = 0; i < ulCtPts; ++i) { verts[i].i = i; } - //std::sort(verts.begin(), verts.end()); + // std::sort(verts.begin(), verts.end()); int threads = QThread::idealThreadCount(); MeshCore::parallel_sort(verts.begin(), verts.end(), std::less<>(), threads); @@ -342,25 +376,26 @@ void MeshFastBuilder::Finish () size_type vertex_count = 0; for (QVector::iterator v = verts.begin(); v != verts.end(); ++v) { - if (!vertex_count || *v != verts[vertex_count-1]) + if (!vertex_count || *v != verts[vertex_count - 1]) { verts[vertex_count++] = *v; + } indices[v->i] = static_cast(vertex_count - 1); } - size_type ulCt = verts.size()/3; + size_type ulCt = verts.size() / 3; MeshFacetArray rFacets(static_cast(ulCt)); - for (size_type i=0; i < ulCt; ++i) { - rFacets[static_cast(i)]._aulPoints[0] = indices[3*i]; - rFacets[static_cast(i)]._aulPoints[1] = indices[3*i + 1]; - rFacets[static_cast(i)]._aulPoints[2] = indices[3*i + 2]; + for (size_type i = 0; i < ulCt; ++i) { + rFacets[static_cast(i)]._aulPoints[0] = indices[3 * i]; + rFacets[static_cast(i)]._aulPoints[1] = indices[3 * i + 1]; + rFacets[static_cast(i)]._aulPoints[2] = indices[3 * i + 2]; } verts.resize(vertex_count); MeshPointArray rPoints; rPoints.reserve(static_cast(vertex_count)); - for (const auto & v : verts) { + for (const auto& v : verts) { rPoints.push_back(MeshPoint(v.x, v.y, v.z)); } diff --git a/src/Mod/Mesh/App/Core/Builder.h b/src/Mod/Mesh/App/Core/Builder.h index 61669ae59b..02da3e5663 100644 --- a/src/Mod/Mesh/App/Core/Builder.h +++ b/src/Mod/Mesh/App/Core/Builder.h @@ -29,7 +29,8 @@ #include "MeshKernel.h" -namespace Base { +namespace Base +{ class SequencerLauncher; } @@ -63,37 +64,35 @@ private: //@{ class Edge { - public: + public: PointIndex pt1; PointIndex pt2; FacetIndex facetIdx; - Edge (PointIndex p1, PointIndex p2, FacetIndex idx) + Edge(PointIndex p1, PointIndex p2, FacetIndex idx) { facetIdx = idx; - if (p1 > p2) - { + if (p1 > p2) { pt1 = p2; pt2 = p1; } - else - { + else { pt1 = p1; pt2 = p2; } } - bool operator < (const Edge &e) const + bool operator<(const Edge& e) const { return (pt1 == e.pt1) ? (pt2 < e.pt2) : (pt1 < e.pt1); } - bool operator > (const Edge &e) const + bool operator>(const Edge& e) const { return (pt1 == e.pt1) ? (pt2 > e.pt2) : (pt1 > e.pt1); } - bool operator == (const Edge &e) const + bool operator==(const Edge& e) const { return (pt1 == e.pt1) && (pt2 == e.pt2); } @@ -102,19 +101,20 @@ private: MeshKernel& _meshKernel; std::set _points; - Base::SequencerLauncher* _seq{nullptr}; + Base::SequencerLauncher* _seq {nullptr}; // keep an array of iterators pointing to the vertex inside the set to save memory using MeshPointIterator = std::pair::iterator, bool>; std::vector _pointsIterator; - size_t _ptIdx{0}; + size_t _ptIdx {0}; - void SetNeighbourhood (); - // As it's forbidden to insert a degenerated facet but insert its vertices anyway we must remove them + void SetNeighbourhood(); + // As it's forbidden to insert a degenerated facet but insert its vertices anyway we must remove + // them void RemoveUnreferencedPoints(); public: - explicit MeshBuilder(MeshKernel &rclM); + explicit MeshBuilder(MeshKernel& rclM); ~MeshBuilder(); /** @@ -130,7 +130,7 @@ public: * AddFacet(), otherwise you'll possibly run into wastage of memory * and performance problems. */ - void Initialize (size_t ctFacets, bool deletion = true); + void Initialize(size_t ctFacets, bool deletion = true); /** adding facets */ /** Add new facet @@ -138,17 +138,22 @@ public: * @param takeFlag if true the flag from the MeshGeomFacet will be taken * @param takeProperty */ - void AddFacet (const MeshGeomFacet& facet, bool takeFlag = false, bool takeProperty = false); + void AddFacet(const MeshGeomFacet& facet, bool takeFlag = false, bool takeProperty = false); /** Add new facet */ - void AddFacet (const Base::Vector3f& pt1, const Base::Vector3f& pt2, const Base::Vector3f& pt3, const Base::Vector3f& normal, unsigned char flag = 0, unsigned long prop = 0); + void AddFacet(const Base::Vector3f& pt1, + const Base::Vector3f& pt2, + const Base::Vector3f& pt3, + const Base::Vector3f& normal, + unsigned char flag = 0, + unsigned long prop = 0); /** Add new facet * @param facetPoints Array of vectors (size 4) in order of vec1, vec2, * vec3, normal * @param flag * @param prop */ - void AddFacet (Base::Vector3f* facetPoints, unsigned char flag = 0, unsigned long prop = 0); + void AddFacet(Base::Vector3f* facetPoints, unsigned char flag = 0, unsigned long prop = 0); /** Finishes building up the mesh structure. Must be done after adding facets. * @param freeMemory if false (default) only the memory of internal @@ -158,7 +163,7 @@ public: * Initialize() then absolutely no memory is wasted and you can leave the * default value. */ - void Finish (bool freeMemory=false); + void Finish(bool freeMemory = false); friend class MeshKernel; @@ -190,29 +195,29 @@ private: public: using size_type = int; - explicit MeshFastBuilder(MeshKernel &rclM); + explicit MeshFastBuilder(MeshKernel& rclM); ~MeshFastBuilder(); /** Initializes the class. Must be done before adding facets * @param ctFacets count of facets. */ - void Initialize (size_type ctFacets); + void Initialize(size_type ctFacets); /** Add new facet */ - void AddFacet (const Base::Vector3f* facetPoints); + void AddFacet(const Base::Vector3f* facetPoints); /** Add new facet */ - void AddFacet (const MeshGeomFacet& facetPoints); + void AddFacet(const MeshGeomFacet& facetPoints); /** Finishes building up the mesh structure. Must be done after adding facets. */ - void Finish (); + void Finish(); private: struct Private; Private* p; }; -} // namespace MeshCore +} // namespace MeshCore #endif diff --git a/src/Mod/Mesh/App/Core/Curvature.cpp b/src/Mod/Mesh/App/Core/Curvature.cpp index 954c2c16db..d60463f040 100644 --- a/src/Mod/Mesh/App/Core/Curvature.cpp +++ b/src/Mod/Mesh/App/Core/Curvature.cpp @@ -22,8 +22,8 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include +#include +#include #endif #include @@ -33,15 +33,15 @@ #include #include -//#define OPTIMIZE_CURVATURE +// #define OPTIMIZE_CURVATURE #ifdef OPTIMIZE_CURVATURE -# include +#include #else -# include +#include #endif -#include "Curvature.h" #include "Approximation.h" +#include "Curvature.h" #include "Iterator.h" #include "MeshKernel.h" #include "Tools.h" @@ -51,16 +51,20 @@ using namespace MeshCore; namespace sp = std::placeholders; MeshCurvature::MeshCurvature(const MeshKernel& kernel) - : myKernel(kernel), myMinPoints(20), myRadius(0.5f) + : myKernel(kernel) + , myMinPoints(20) + , myRadius(0.5f) { mySegment.resize(kernel.CountFacets()); std::generate(mySegment.begin(), mySegment.end(), Base::iotaGen(0)); } MeshCurvature::MeshCurvature(const MeshKernel& kernel, const std::vector& segm) - : myKernel(kernel), myMinPoints(20), myRadius(0.5f), mySegment(segm) -{ -} + : myKernel(kernel) + , myMinPoints(20) + , myRadius(0.5f) + , mySegment(segm) +{} void MeshCurvature::ComputePerFace(bool parallel) { @@ -77,50 +81,48 @@ void MeshCurvature::ComputePerFace(bool parallel) } } else { - //NOLINTBEGIN - QFuture future = QtConcurrent::mapped - (mySegment, std::bind(&FacetCurvature::Compute, &face, sp::_1)); - //NOLINTEND + // NOLINTBEGIN + QFuture future = + QtConcurrent::mapped(mySegment, std::bind(&FacetCurvature::Compute, &face, sp::_1)); + // NOLINTEND QFutureWatcher watcher; watcher.setFuture(future); watcher.waitForFinished(); - for (const auto & it : future) { + for (const auto& it : future) { myCurvature.push_back(it); } } } #ifdef OPTIMIZE_CURVATURE -namespace MeshCore { -void GenerateComplementBasis (Eigen::Vector3f& rkU, Eigen::Vector3f& rkV, - const Eigen::Vector3f& rkW) +namespace MeshCore +{ +void GenerateComplementBasis(Eigen::Vector3f& rkU, Eigen::Vector3f& rkV, const Eigen::Vector3f& rkW) { float fInvLength; - if (fabs(rkW[0]) >= fabs(rkW[1])) - { + if (fabs(rkW[0]) >= fabs(rkW[1])) { // W.x or W.z is the largest magnitude component, swap them - fInvLength = 1.0/sqrt(rkW[0]*rkW[0] + rkW[2]*rkW[2]); - rkU[0] = -rkW[2]*fInvLength; - rkU[1] = 0.0; - rkU[2] = +rkW[0]*fInvLength; - rkV[0] = rkW[1]*rkU[2]; - rkV[1] = rkW[2]*rkU[0] - rkW[0]*rkU[2]; - rkV[2] = -rkW[1]*rkU[0]; + fInvLength = 1.0 / sqrt(rkW[0] * rkW[0] + rkW[2] * rkW[2]); + rkU[0] = -rkW[2] * fInvLength; + rkU[1] = 0.0; + rkU[2] = +rkW[0] * fInvLength; + rkV[0] = rkW[1] * rkU[2]; + rkV[1] = rkW[2] * rkU[0] - rkW[0] * rkU[2]; + rkV[2] = -rkW[1] * rkU[0]; } - else - { + else { // W.y or W.z is the largest magnitude component, swap them - fInvLength = 1.0/sqrt(rkW[1]*rkW[1] + rkW[2]*rkW[2]); - rkU[0] = 0.0; - rkU[1] = +rkW[2]*fInvLength; - rkU[2] = -rkW[1]*fInvLength; - rkV[0] = rkW[1]*rkU[2] - rkW[2]*rkU[1]; - rkV[1] = -rkW[0]*rkU[2]; - rkV[2] = rkW[0]*rkU[1]; + fInvLength = 1.0 / sqrt(rkW[1] * rkW[1] + rkW[2] * rkW[2]); + rkU[0] = 0.0; + rkU[1] = +rkW[2] * fInvLength; + rkU[2] = -rkW[1] * fInvLength; + rkV[0] = rkW[1] * rkU[2] - rkW[2] * rkU[1]; + rkV[1] = -rkW[0] * rkU[2]; + rkV[2] = rkW[0] * rkU[1]; } } -} +} // namespace MeshCore void MeshCurvature::ComputePerVertex() { @@ -136,7 +138,7 @@ void MeshCurvature::ComputePerVertex() std::vector akNormal(numPoints); std::vector akVertex(numPoints); - for (unsigned long i=0; i= kW1.squaredNorm()) - { + Eigen::Vector2f kW0(kS(0, 1), minCurvature - kS(0, 0)); + Eigen::Vector2f kW1(minCurvature - kS(1, 1), kS(1, 0)); + if (kW0.squaredNorm() >= kW1.squaredNorm()) { float len = kW0.squaredNorm(); - if (len > 0 && len != 1) + if (len > 0 && len != 1) { kW0.normalize(); - Eigen::Vector3f v = kU*kW0[0] + kV*kW0[1]; - minDirection.Set(v[0],v[1],v[2]); + } + Eigen::Vector3f v = kU * kW0[0] + kV * kW0[1]; + minDirection.Set(v[0], v[1], v[2]); } - else - { + else { float len = kW1.squaredNorm(); - if (len > 0 && len != 1) + if (len > 0 && len != 1) { kW1.normalize(); - Eigen::Vector3f v = kU*kW1[0] + kV*kW1[1]; - minDirection.Set(v[0],v[1],v[2]); + } + Eigen::Vector3f v = kU * kW1[0] + kV * kW1[1]; + minDirection.Set(v[0], v[1], v[2]); } - kW0 = Eigen::Vector2f(kS(0,1),maxCurvature-kS(0,0)); - kW1 = Eigen::Vector2f(maxCurvature-kS(1,1),kS(1,0)); - if (kW0.squaredNorm() >= kW1.squaredNorm()) - { + kW0 = Eigen::Vector2f(kS(0, 1), maxCurvature - kS(0, 0)); + kW1 = Eigen::Vector2f(maxCurvature - kS(1, 1), kS(1, 0)); + if (kW0.squaredNorm() >= kW1.squaredNorm()) { float len = kW0.squaredNorm(); - if (len > 0 && len != 1) + if (len > 0 && len != 1) { kW0.normalize(); - Eigen::Vector3f v = kU*kW0[0] + kV*kW0[1]; - maxDirection.Set(v[0],v[1],v[2]); + } + Eigen::Vector3f v = kU * kW0[0] + kV * kW0[1]; + maxDirection.Set(v[0], v[1], v[2]); } - else - { + else { float len = kW1.squaredNorm(); - if (len > 0 && len != 1) + if (len > 0 && len != 1) { kW1.normalize(); - Eigen::Vector3f v = kU*kW1[0] + kV*kW1[1]; - maxDirection.Set(v[0],v[1],v[2]); + } + Eigen::Vector3f v = kU * kW1[0] + kV * kW1[1]; + maxDirection.Set(v[0], v[1], v[2]); } CurvatureInfo ci; @@ -294,7 +294,7 @@ void MeshCurvature::ComputePerVertex() myCurvature.clear(); // get all points - std::vector< Wm4::Vector3 > aPnts; + std::vector> aPnts; aPnts.reserve(myKernel.CountPoints()); MeshPointIterator cPIt(myKernel); for (cPIt.Init(); cPIt.More(); cPIt.Next()) { @@ -304,20 +304,24 @@ void MeshCurvature::ComputePerVertex() // get all point connections std::vector aIdx; - aIdx.reserve(3*myKernel.CountFacets()); + aIdx.reserve(3 * myKernel.CountFacets()); const MeshFacetArray& raFts = myKernel.GetFacets(); - for (const auto & it : raFts) { + for (const auto& it : raFts) { for (PointIndex point : it._aulPoints) { aIdx.push_back(int(point)); } } // in case of an empty mesh no curvature can be calculated - if (myKernel.CountPoints() == 0 || myKernel.CountFacets() == 0) + if (myKernel.CountPoints() == 0 || myKernel.CountFacets() == 0) { return; + } // compute vertex based curvatures - Wm4::MeshCurvature meshCurv(myKernel.CountPoints(), &(aPnts[0]), myKernel.CountFacets(), &(aIdx[0])); + Wm4::MeshCurvature meshCurv(myKernel.CountPoints(), + &(aPnts[0]), + myKernel.CountFacets(), + &(aIdx[0])); // get curvature information now const Wm4::Vector3* aMaxCurvDir = meshCurv.GetMaxDirections(); @@ -326,24 +330,31 @@ void MeshCurvature::ComputePerVertex() const double* aMinCurv = meshCurv.GetMinCurvatures(); myCurvature.reserve(myKernel.CountPoints()); - for (unsigned long i=0; i& ind) : indices(ind){} + explicit FitPointCollector(std::set& ind) + : indices(ind) + {} void Append(const MeshCore::MeshKernel& kernel, FacetIndex index) override { PointIndex ulP1, ulP2, ulP3; @@ -356,14 +367,19 @@ public: private: std::set& indices; }; -} +} // namespace MeshCore // -------------------------------------------------------- -FacetCurvature::FacetCurvature(const MeshKernel& kernel, const MeshRefPointToFacets& search, float r, unsigned long pt) - : myKernel(kernel), mySearch(search), myMinPoints(pt), myRadius(r) -{ -} +FacetCurvature::FacetCurvature(const MeshKernel& kernel, + const MeshRefPointToFacets& search, + float r, + unsigned long pt) + : myKernel(kernel) + , mySearch(search) + , myMinPoints(pt) + , myRadius(r) +{} CurvatureInfo FacetCurvature::Compute(FacetIndex index) const { @@ -377,16 +393,16 @@ CurvatureInfo FacetCurvature::Compute(FacetIndex index) const FitPointCollector collect(point_indices); float searchDist = myRadius; - int attempts=0; + int attempts = 0; do { mySearch.Neighbours(index, searchDist, collect); - if (point_indices.empty()) + if (point_indices.empty()) { break; + } float min_points = myMinPoints; float use_points = point_indices.size(); - searchDist = searchDist * sqrt(min_points/use_points); - } - while((point_indices.size() < myMinPoints) && (attempts++ < 3)); + searchDist = searchDist * sqrt(min_points / use_points); + } while ((point_indices.size() < myMinPoints) && (attempts++ < 3)); std::vector fitPoints; const MeshPointArray& verts = myKernel.GetPoints(); @@ -436,8 +452,8 @@ CurvatureInfo FacetCurvature::Compute(FacetIndex index) const if (rkNormal * face_normal < 0.0) { // Note: Changing the normal directions is similar to flipping over the object. // In this case we must adjust the curvature information as well. - std::swap(info.cMaxCurvDir,info.cMinCurvDir); - std::swap(info.fMaxCurvature,info.fMinCurvature); + std::swap(info.cMaxCurvDir, info.cMinCurvDir); + std::swap(info.fMaxCurvature, info.fMinCurvature); info.fMaxCurvature *= (-1.0); info.fMinCurvature *= (-1.0); } diff --git a/src/Mod/Mesh/App/Core/Curvature.h b/src/Mod/Mesh/App/Core/Curvature.h index 111c855a76..9f724d1491 100644 --- a/src/Mod/Mesh/App/Core/Curvature.h +++ b/src/Mod/Mesh/App/Core/Curvature.h @@ -23,11 +23,12 @@ #ifndef MESHCORE_CURVATURE_H #define MESHCORE_CURVATURE_H -#include -#include #include "Definitions.h" +#include +#include -namespace MeshCore { +namespace MeshCore +{ class MeshKernel; class MeshRefPointToFacets; @@ -42,7 +43,10 @@ struct MeshExport CurvatureInfo class MeshExport FacetCurvature { public: - FacetCurvature(const MeshKernel& kernel, const MeshRefPointToFacets& search, float, unsigned long); + FacetCurvature(const MeshKernel& kernel, + const MeshRefPointToFacets& search, + float, + unsigned long); CurvatureInfo Compute(FacetIndex index) const; private: @@ -57,11 +61,20 @@ class MeshExport MeshCurvature public: explicit MeshCurvature(const MeshKernel& kernel); MeshCurvature(const MeshKernel& kernel, const std::vector& segm); - float GetRadius() const { return myRadius; } - void SetRadius(float r) { myRadius = r; } + float GetRadius() const + { + return myRadius; + } + void SetRadius(float r) + { + myRadius = r; + } void ComputePerFace(bool parallel); void ComputePerVertex(); - const std::vector& GetCurvature() const { return myCurvature; } + const std::vector& GetCurvature() const + { + return myCurvature; + } private: const MeshKernel& myKernel; @@ -71,6 +84,6 @@ private: std::vector myCurvature; }; -} // MeshCore +} // namespace MeshCore -#endif // MESHCORE_CURVATURE_H +#endif // MESHCORE_CURVATURE_H diff --git a/src/Mod/Mesh/App/Core/CylinderFit.cpp b/src/Mod/Mesh/App/Core/CylinderFit.cpp index 3ccdbec122..194ef85306 100644 --- a/src/Mod/Mesh/App/Core/CylinderFit.cpp +++ b/src/Mod/Mesh/App/Core/CylinderFit.cpp @@ -56,9 +56,9 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include +#include +#include +#include #endif #include @@ -70,96 +70,114 @@ using namespace MeshCoreFit; CylinderFit::CylinderFit() - : _vBase(0,0,0) - , _vAxis(0,0,1) -{ -} + : _vBase(0, 0, 0) + , _vAxis(0, 0, 1) +{} // Set approximations before calling the fitting -void CylinderFit::SetApproximations(double radius, const Base::Vector3d &base, const Base::Vector3d &axis) +void CylinderFit::SetApproximations(double radius, + const Base::Vector3d& base, + const Base::Vector3d& axis) { - _bIsFitted = false; - _fLastResult = FLOAT_MAX; - _numIter = 0; - _dRadius = radius; - _vBase = base; - _vAxis = axis; - _vAxis.Normalize(); + _bIsFitted = false; + _fLastResult = FLOAT_MAX; + _numIter = 0; + _dRadius = radius; + _vBase = base; + _vAxis = axis; + _vAxis.Normalize(); } // Set approximations before calling the fitting. This version computes the radius // using the given axis and the existing surface points (which must already be added!) -void CylinderFit::SetApproximations(const Base::Vector3d &base, const Base::Vector3d &axis) +void CylinderFit::SetApproximations(const Base::Vector3d& base, const Base::Vector3d& axis) { - _bIsFitted = false; - _fLastResult = FLOAT_MAX; - _numIter = 0; - _vBase = base; - _vAxis = axis; - _vAxis.Normalize(); - _dRadius = 0.0; - if (!_vPoints.empty()) - { - for (std::list< Base::Vector3f >::const_iterator cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) - _dRadius += Base::Vector3d(cIt->x, cIt->y, cIt->z).DistanceToLine(_vBase, _vAxis); - _dRadius /= (double)_vPoints.size(); - } + _bIsFitted = false; + _fLastResult = FLOAT_MAX; + _numIter = 0; + _vBase = base; + _vAxis = axis; + _vAxis.Normalize(); + _dRadius = 0.0; + if (!_vPoints.empty()) { + for (std::list::const_iterator cIt = _vPoints.begin(); + cIt != _vPoints.end(); + ++cIt) { + _dRadius += Base::Vector3d(cIt->x, cIt->y, cIt->z).DistanceToLine(_vBase, _vAxis); + } + _dRadius /= (double)_vPoints.size(); + } } // Set iteration convergence criteria for the fit if special values are needed. // The default values set in the constructor are suitable for most uses -void CylinderFit::SetConvergenceCriteria(double posConvLimit, double dirConvLimit, double vConvLimit, int maxIter) +void CylinderFit::SetConvergenceCriteria(double posConvLimit, + double dirConvLimit, + double vConvLimit, + int maxIter) { - if (posConvLimit > 0.0) - _posConvLimit = posConvLimit; - if (dirConvLimit > 0.0) - _dirConvLimit = dirConvLimit; - if (vConvLimit > 0.0) - _vConvLimit = vConvLimit; - if (maxIter > 0) - _maxIter = maxIter; + if (posConvLimit > 0.0) { + _posConvLimit = posConvLimit; + } + if (dirConvLimit > 0.0) { + _dirConvLimit = dirConvLimit; + } + if (vConvLimit > 0.0) { + _vConvLimit = vConvLimit; + } + if (maxIter > 0) { + _maxIter = maxIter; + } } double CylinderFit::GetRadius() const { - if (_bIsFitted) - return _dRadius; - else - return 0.0; + if (_bIsFitted) { + return _dRadius; + } + else { + return 0.0; + } } Base::Vector3d CylinderFit::GetBase() const { - if (_bIsFitted) + if (_bIsFitted) { return _vBase; - else + } + else { return Base::Vector3d(); + } } Base::Vector3d CylinderFit::GetAxis() const { - if (_bIsFitted) + if (_bIsFitted) { return _vAxis; - else + } + else { return Base::Vector3d(); + } } int CylinderFit::GetNumIterations() const { - if (_bIsFitted) - return _numIter; - else - return 0; + if (_bIsFitted) { + return _numIter; + } + else { + return 0; + } } -float CylinderFit::GetDistanceToCylinder(const Base::Vector3f &rcPoint) const +float CylinderFit::GetDistanceToCylinder(const Base::Vector3f& rcPoint) const { float fResult = FLOAT_MAX; - if (_bIsFitted) - { - fResult = Base::Vector3d(rcPoint.x, rcPoint.y, rcPoint.z).DistanceToLine(_vBase, _vAxis) - _dRadius; - } + if (_bIsFitted) { + fResult = Base::Vector3d(rcPoint.x, rcPoint.y, rcPoint.z).DistanceToLine(_vBase, _vAxis) + - _dRadius; + } return fResult; } @@ -168,13 +186,14 @@ float CylinderFit::GetStdDeviation() const // Mean: M=(1/N)*SUM Xi // Variance: VAR=(N/N-1)*[(1/N)*SUM(Xi^2)-M^2] // Standard deviation: SD=SQRT(VAR) - if (!_bIsFitted) + if (!_bIsFitted) { return FLOAT_MAX; + } double sumXi = 0.0, sumXi2 = 0.0, dist = 0.0; for (auto it : _vPoints) { - dist = GetDistanceToCylinder( it ); - sumXi += dist; + dist = GetDistanceToCylinder(it); + sumXi += dist; sumXi2 += (dist * dist); } @@ -188,7 +207,7 @@ void CylinderFit::ProjectToCylinder() Base::Vector3f cBase(_vBase.x, _vBase.y, _vBase.z); Base::Vector3f cAxis(_vAxis.x, _vAxis.y, _vAxis.z); - for (auto & cPnt : _vPoints) { + for (auto& cPnt : _vPoints) { if (cPnt.DistanceToLine(cBase, cAxis) > 0) { Base::Vector3f proj; cBase.ProjectToPlane(cPnt, cAxis, proj); @@ -204,9 +223,8 @@ void CylinderFit::ProjectToCylinder() float x = (float(rand()) / float(RAND_MAX)); float y = (float(rand()) / float(RAND_MAX)); float z = (float(rand()) / float(RAND_MAX)); - cMov.Move(x,y,z); - } - while (cMov.DistanceToLine(cBase, cAxis) == 0); + cMov.Move(x, y, z); + } while (cMov.DistanceToLine(cBase, cAxis) == 0); Base::Vector3f proj; cMov.ProjectToPlane(cPnt, cAxis, proj); @@ -223,25 +241,31 @@ void CylinderFit::ProjectToCylinder() // In that case rather use SetApproximations() with a better estimate. void CylinderFit::ComputeApproximationsLine() { - _bIsFitted = false; - _fLastResult = FLOAT_MAX; - _numIter = 0; - _vBase.Set(0.0, 0.0, 0.0); - _vAxis.Set(0.0, 0.0, 0.0); - _dRadius = 0.0; - if (!_vPoints.empty()) - { - std::vector input; - std::transform(_vPoints.begin(), _vPoints.end(), std::back_inserter(input), - [](const Base::Vector3f& v) { return Wm4::Vector3d(v.x, v.y, v.z); }); - Wm4::Line3 kLine = Wm4::OrthogonalLineFit3(input.size(), input.data()); - _vBase.Set(kLine.Origin.X(), kLine.Origin.Y(), kLine.Origin.Z()); - _vAxis.Set(kLine.Direction.X(), kLine.Direction.Y(), kLine.Direction.Z()); + _bIsFitted = false; + _fLastResult = FLOAT_MAX; + _numIter = 0; + _vBase.Set(0.0, 0.0, 0.0); + _vAxis.Set(0.0, 0.0, 0.0); + _dRadius = 0.0; + if (!_vPoints.empty()) { + std::vector input; + std::transform(_vPoints.begin(), + _vPoints.end(), + std::back_inserter(input), + [](const Base::Vector3f& v) { + return Wm4::Vector3d(v.x, v.y, v.z); + }); + Wm4::Line3 kLine = Wm4::OrthogonalLineFit3(input.size(), input.data()); + _vBase.Set(kLine.Origin.X(), kLine.Origin.Y(), kLine.Origin.Z()); + _vAxis.Set(kLine.Direction.X(), kLine.Direction.Y(), kLine.Direction.Z()); - for (std::list< Base::Vector3f >::const_iterator cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) - _dRadius += Base::Vector3d(cIt->x, cIt->y, cIt->z).DistanceToLine(_vBase, _vAxis); - _dRadius /= (double)_vPoints.size(); - } + for (std::list::const_iterator cIt = _vPoints.begin(); + cIt != _vPoints.end(); + ++cIt) { + _dRadius += Base::Vector3d(cIt->x, cIt->y, cIt->z).DistanceToLine(_vBase, _vAxis); + } + _dRadius /= (double)_vPoints.size(); + } } float CylinderFit::Fit() @@ -251,12 +275,14 @@ float CylinderFit::Fit() _numIter = 0; // A minimum of 5 surface points is needed to define a cylinder - if (CountPoints() < 5) + if (CountPoints() < 5) { return FLOAT_MAX; + } // If approximations have not been set/computed then compute some now using the line fit method - if (_dRadius == 0.0) + if (_dRadius == 0.0) { ComputeApproximationsLine(); + } // Check parameters to define the best solution direction // There are 7 parameters but 2 are actually dependent on the others @@ -269,48 +295,56 @@ float CylinderFit::Fit() findBestSolDirection(solDir); // Initialise some matrices and vectors - std::vector< Base::Vector3d > residuals(CountPoints(), Base::Vector3d(0.0, 0.0, 0.0)); + std::vector residuals(CountPoints(), Base::Vector3d(0.0, 0.0, 0.0)); Matrix5x5 atpa; Eigen::VectorXd atpl(5); // Iteration loop... double sigma0; bool cont = true; - while (cont && (_numIter < _maxIter)) - { + while (cont && (_numIter < _maxIter)) { ++_numIter; // Set up the quasi parametric normal equations setupNormalEquationMatrices(solDir, residuals, atpa, atpl); // Solve the equations for the unknown corrections - Eigen::LLT< Matrix5x5 > llt(atpa); - if (llt.info() != Eigen::Success) + Eigen::LLT llt(atpa); + if (llt.info() != Eigen::Success) { return FLOAT_MAX; + } Eigen::VectorXd x = llt.solve(atpl); // Check parameter convergence cont = false; - if ((fabs(x(0)) > _posConvLimit) || (fabs(x(1)) > _posConvLimit) || // the two position parameter corrections - (fabs(x(2)) > _dirConvLimit) || (fabs(x(3)) > _dirConvLimit) || // the two direction parameter corrections - (fabs(x(4)) > _posConvLimit)) // the radius correction + if ((fabs(x(0)) > _posConvLimit) || (fabs(x(1)) > _posConvLimit) + || // the two position parameter corrections + (fabs(x(2)) > _dirConvLimit) || (fabs(x(3)) > _dirConvLimit) + || // the two direction parameter corrections + (fabs(x(4)) > _posConvLimit)) { // the radius correction cont = true; + } - // Before updating the unknowns, compute the residuals and sigma0 and check the residual convergence + // Before updating the unknowns, compute the residuals and sigma0 and check the residual + // convergence bool vConverged; - if (!computeResiduals(solDir, x, residuals, sigma0, _vConvLimit, vConverged)) + if (!computeResiduals(solDir, x, residuals, sigma0, _vConvLimit, vConverged)) { return FLOAT_MAX; - if (!vConverged) + } + if (!vConverged) { cont = true; + } // Update the parameters - if (!updateParameters(solDir, x)) + if (!updateParameters(solDir, x)) { return FLOAT_MAX; + } } // Check for convergence - if (cont) + if (cont) { return FLOAT_MAX; + } _bIsFitted = true; _fLastResult = sigma0; @@ -320,121 +354,129 @@ float CylinderFit::Fit() // Checks initial parameter values and defines the best solution direction to use // Axis direction = (L,M,N) -// solution L: L is biggest axis component and L = f(M,N) and X = Mx (we move the base point along axis to this x-value) -// solution M: M is biggest axis component and M = f(L,N) and Y = My (we move the base point along axis to this y-value) -// solution N: N is biggest axis component and N = f(L,M) and Z = Mz (we move the base point along axis to this z-value) -// where (Mx,My,Mz) is the mean of the input points (centre of gravity) -void CylinderFit::findBestSolDirection(SolutionD &solDir) +// solution L: L is biggest axis component and L = f(M,N) and X = Mx (we move the base point along +// axis to this x-value) solution M: M is biggest axis component and M = f(L,N) and Y = My (we move +// the base point along axis to this y-value) solution N: N is biggest axis component and N = f(L,M) +// and Z = Mz (we move the base point along axis to this z-value) where (Mx,My,Mz) is the mean of +// the input points (centre of gravity) +void CylinderFit::findBestSolDirection(SolutionD& solDir) { - // Choose the best of the three solution 'directions' to use - // This is to avoid a square root of a negative number when computing the dependent parameters - Base::Vector3d dir = _vAxis; - Base::Vector3d pos = _vBase; - dir.Normalize(); - double biggest = dir.x; - solDir = solL; - if (fabs (dir.y) > fabs (biggest)) - { - biggest = dir.y; - solDir = solM; - } - if (fabs (dir.z) > fabs (biggest)) - { - biggest = dir.z; - solDir = solN; - } - if (biggest < 0.0) - dir.Set(-dir.x, -dir.y, -dir.z); // multiplies by -1 + // Choose the best of the three solution 'directions' to use + // This is to avoid a square root of a negative number when computing the dependent parameters + Base::Vector3d dir = _vAxis; + Base::Vector3d pos = _vBase; + dir.Normalize(); + double biggest = dir.x; + solDir = solL; + if (fabs(dir.y) > fabs(biggest)) { + biggest = dir.y; + solDir = solM; + } + if (fabs(dir.z) > fabs(biggest)) { + biggest = dir.z; + solDir = solN; + } + if (biggest < 0.0) { + dir.Set(-dir.x, -dir.y, -dir.z); // multiplies by -1 + } - double fixedVal = 0.0; - double lambda; - switch (solDir) - { - case solL: - fixedVal = meanXObs(); - lambda = (fixedVal - pos.x) / dir.x; - pos.x = fixedVal; - pos.y = pos.y + lambda * dir.y; - pos.z = pos.z + lambda * dir.z; - break; - case solM: - fixedVal = meanYObs(); - lambda = (fixedVal - pos.y) / dir.y; - pos.x = pos.x + lambda * dir.x; - pos.y = fixedVal; - pos.z = pos.z + lambda * dir.z; - break; - case solN: - fixedVal = meanZObs(); - lambda = (fixedVal - pos.z) / dir.z; - pos.x = pos.x + lambda * dir.x; - pos.y = pos.y + lambda * dir.y; - pos.z = fixedVal; - break; - } - _vAxis = dir; - _vBase = pos; + double fixedVal = 0.0; + double lambda; + switch (solDir) { + case solL: + fixedVal = meanXObs(); + lambda = (fixedVal - pos.x) / dir.x; + pos.x = fixedVal; + pos.y = pos.y + lambda * dir.y; + pos.z = pos.z + lambda * dir.z; + break; + case solM: + fixedVal = meanYObs(); + lambda = (fixedVal - pos.y) / dir.y; + pos.x = pos.x + lambda * dir.x; + pos.y = fixedVal; + pos.z = pos.z + lambda * dir.z; + break; + case solN: + fixedVal = meanZObs(); + lambda = (fixedVal - pos.z) / dir.z; + pos.x = pos.x + lambda * dir.x; + pos.y = pos.y + lambda * dir.y; + pos.z = fixedVal; + break; + } + _vAxis = dir; + _vBase = pos; } double CylinderFit::meanXObs() { - double mx = 0.0; - if (!_vPoints.empty()) - { - for (std::list::const_iterator cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) - mx += cIt->x; - mx /= double(_vPoints.size()); - } - return mx; + double mx = 0.0; + if (!_vPoints.empty()) { + for (std::list::const_iterator cIt = _vPoints.begin(); + cIt != _vPoints.end(); + ++cIt) { + mx += cIt->x; + } + mx /= double(_vPoints.size()); + } + return mx; } double CylinderFit::meanYObs() { - double my = 0.0; - if (!_vPoints.empty()) - { - for (std::list::const_iterator cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) - my += cIt->y; - my /= double(_vPoints.size()); - } - return my; + double my = 0.0; + if (!_vPoints.empty()) { + for (std::list::const_iterator cIt = _vPoints.begin(); + cIt != _vPoints.end(); + ++cIt) { + my += cIt->y; + } + my /= double(_vPoints.size()); + } + return my; } double CylinderFit::meanZObs() { - double mz = 0.0; - if (!_vPoints.empty()) - { - for (std::list::const_iterator cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) - mz += cIt->z; - mz /= double(_vPoints.size()); - } - return mz; + double mz = 0.0; + if (!_vPoints.empty()) { + for (std::list::const_iterator cIt = _vPoints.begin(); + cIt != _vPoints.end(); + ++cIt) { + mz += cIt->z; + } + mz /= double(_vPoints.size()); + } + return mz; } // Set up the normal equation matrices // atpa ... 5x5 normal matrix // atpl ... 5x1 matrix (right-hand side of equation) -void CylinderFit::setupNormalEquationMatrices(SolutionD solDir, const std::vector< Base::Vector3d > &residuals, Matrix5x5 &atpa, Eigen::VectorXd &atpl) const +void CylinderFit::setupNormalEquationMatrices(SolutionD solDir, + const std::vector& residuals, + Matrix5x5& atpa, + Eigen::VectorXd& atpl) const { - // Zero matrices - atpa.setZero(); - atpl.setZero(); + // Zero matrices + atpa.setZero(); + atpl.setZero(); - // For each point, setup the observation equation coefficients and add their - // contribution into the normal equation matrices - double a[5], b[3]; - double f0, qw; - std::vector< Base::Vector3d >::const_iterator vIt = residuals.begin(); - std::list< Base::Vector3f >::const_iterator cIt; - for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt, ++vIt) - { - // if (using this point) { // currently all given points are used (could modify this if eliminating outliers, etc.... - setupObservation(solDir, *cIt, *vIt, a, f0, qw, b); - addObservationU(a, f0, qw, atpa, atpl); - // } - } - setLowerPart(atpa); + // For each point, setup the observation equation coefficients and add their + // contribution into the normal equation matrices + double a[5], b[3]; + double f0, qw; + std::vector::const_iterator vIt = residuals.begin(); + std::list::const_iterator cIt; + for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt, ++vIt) { + // if (using this point) { // currently all given points are used (could modify this if + // eliminating outliers, etc.... + setupObservation(solDir, *cIt, *vIt, a, f0, qw, b); + addObservationU(a, f0, qw, atpa, atpl); + // } + } + setLowerPart(atpa); } // Sets up contributions of given observation to the quasi parametric @@ -443,93 +485,115 @@ void CylinderFit::setupNormalEquationMatrices(SolutionD solDir, const std::vecto // residual ... residual for this point computed from previous iteration (zero for first iteration) // a[5] ... parameter partials // f0 ... reference to f0 term -// qw ... reference to quasi weight (here we are assuming equal unit weights for each observed point coordinate) -// b[3] ... observation partials -void CylinderFit::setupObservation(SolutionD solDir, const Base::Vector3f &point, const Base::Vector3d &residual, double a[5], double &f0, double &qw, double b[3]) const +// qw ... reference to quasi weight (here we are assuming equal unit weights for each observed +// point coordinate) b[3] ... observation partials +void CylinderFit::setupObservation(SolutionD solDir, + const Base::Vector3f& point, + const Base::Vector3d& residual, + double a[5], + double& f0, + double& qw, + double b[3]) const { - // This adjustment requires an update of the observation approximations - // because the residuals do not have a linear relationship. - // New estimates for the observations: - double xEstimate = (double)point.x + residual.x; - double yEstimate = (double)point.y + residual.y; - double zEstimate = (double)point.z + residual.z; + // This adjustment requires an update of the observation approximations + // because the residuals do not have a linear relationship. + // New estimates for the observations: + double xEstimate = (double)point.x + residual.x; + double yEstimate = (double)point.y + residual.y; + double zEstimate = (double)point.z + residual.z; - // intermediate parameters - double lambda = _vAxis.x * (xEstimate - _vBase.x) + _vAxis.y * (yEstimate - _vBase.y) + _vAxis.z * (zEstimate - _vBase.z); - double x0 = _vBase.x + lambda * _vAxis.x; - double y0 = _vBase.y + lambda * _vAxis.y; - double z0 = _vBase.z + lambda * _vAxis.z; - double dx = xEstimate - x0; - double dy = yEstimate - y0; - double dz = zEstimate - z0; - double dx00 = _vBase.x - xEstimate; - double dy00 = _vBase.y - yEstimate; - double dz00 = _vBase.z - zEstimate; + // intermediate parameters + double lambda = _vAxis.x * (xEstimate - _vBase.x) + _vAxis.y * (yEstimate - _vBase.y) + + _vAxis.z * (zEstimate - _vBase.z); + double x0 = _vBase.x + lambda * _vAxis.x; + double y0 = _vBase.y + lambda * _vAxis.y; + double z0 = _vBase.z + lambda * _vAxis.z; + double dx = xEstimate - x0; + double dy = yEstimate - y0; + double dz = zEstimate - z0; + double dx00 = _vBase.x - xEstimate; + double dy00 = _vBase.y - yEstimate; + double dz00 = _vBase.z - zEstimate; - // partials of the observations - b[0] = 2.0 * (dx - _vAxis.x * _vAxis.x * dx - _vAxis.x * _vAxis.y * dy - _vAxis.x * _vAxis.z * dz); - b[1] = 2.0 * (dy - _vAxis.x * _vAxis.y * dx - _vAxis.y * _vAxis.y * dy - _vAxis.y * _vAxis.z * dz); - b[2] = 2.0 * (dz - _vAxis.x * _vAxis.z * dx - _vAxis.y * _vAxis.z * dy - _vAxis.z * _vAxis.z * dz); + // partials of the observations + b[0] = + 2.0 * (dx - _vAxis.x * _vAxis.x * dx - _vAxis.x * _vAxis.y * dy - _vAxis.x * _vAxis.z * dz); + b[1] = + 2.0 * (dy - _vAxis.x * _vAxis.y * dx - _vAxis.y * _vAxis.y * dy - _vAxis.y * _vAxis.z * dz); + b[2] = + 2.0 * (dz - _vAxis.x * _vAxis.z * dx - _vAxis.y * _vAxis.z * dy - _vAxis.z * _vAxis.z * dz); - // partials of the parameters - switch (solDir) - { - double ddxdl, ddydl, ddzdl; - double ddxdm, ddydm, ddzdm; - double ddxdn, ddydn, ddzdn; - case solL: - // order of parameters: Yc, Zc, M, N, R - ddxdm = -2.0 * _vAxis.y * dx00 + (_vAxis.x - _vAxis.y * _vAxis.y / _vAxis.x) * dy00 - (_vAxis.y * _vAxis.z / _vAxis.x) * dz00; - ddydm = (_vAxis.x - _vAxis.y * _vAxis.y / _vAxis.x) * dx00 + 2.0 * _vAxis.y * dy00 + _vAxis.z * dz00; - ddzdm = -(_vAxis.y * _vAxis.z / _vAxis.x) * dx00 + _vAxis.z * dy00; - ddxdn = -2.0 * _vAxis.z * dx00 - (_vAxis.y * _vAxis.z / _vAxis.x) * dy00 + (_vAxis.x - _vAxis.z * _vAxis.z / _vAxis.x) * dz00; - ddydn = -(_vAxis.y * _vAxis.z / _vAxis.x) * dx00 + _vAxis.y * dz00; - ddzdn = (_vAxis.x - _vAxis.z * _vAxis.z / _vAxis.x) * dx00 + _vAxis.y * dy00 + 2.0 * _vAxis.z * dz00; - a[0] = -b[1]; - a[1] = -b[2]; - a[2] = 2.0 * (dx * ddxdm + dy * ddydm + dz * ddzdm); - a[3] = 2.0 * (dx * ddxdn + dy * ddydn + dz * ddzdn); - a[4] = -2.0 * _dRadius; - break; - case solM: - // order of parameters: Xc, Zc, L, N, R - ddxdl = 2.0 * _vAxis.x * dx00 + (_vAxis.y - _vAxis.x * _vAxis.x / _vAxis.y) * dy00 + _vAxis.z * dz00; - ddydl = (_vAxis.y - _vAxis.x * _vAxis.x / _vAxis.y) * dx00 - 2.0 * _vAxis.x * dy00 - (_vAxis.x * _vAxis.z / _vAxis.y) * dz00; - ddzdl = _vAxis.z * dx00 - (_vAxis.x * _vAxis.z / _vAxis.y) * dy00; - ddxdn = -(_vAxis.x * _vAxis.z / _vAxis.y) * dy00 + _vAxis.x * dz00; - ddydn = -(_vAxis.x * _vAxis.z / _vAxis.y) * dx00 - 2.0 * _vAxis.z * dy00 + (_vAxis.y - _vAxis.z * _vAxis.z / _vAxis.y) * dz00; - ddzdn = _vAxis.x * dx00 + (_vAxis.y - _vAxis.z * _vAxis.z / _vAxis.y) * dy00 + 2.0 * _vAxis.z * dz00; - a[0] = -b[0]; - a[1] = -b[2]; - a[2] = 2.0 * (dx * ddxdl + dy * ddydl + dz * ddzdl); - a[3] = 2.0 * (dx * ddxdn + dy * ddydn + dz * ddzdn); - a[4] = -2.0 * _dRadius; - break; - case solN: - // order of parameters: Xc, Yc, L, M, R - ddxdl = 2.0 * _vAxis.x * dx00 + _vAxis.y * dy00 + (_vAxis.z - _vAxis.x * _vAxis.x / _vAxis.z) * dz00; - ddydl = _vAxis.y * dx00 - (_vAxis.x * _vAxis.y / _vAxis.z) * dz00; - ddzdl = (_vAxis.z - _vAxis.x * _vAxis.x / _vAxis.z) * dx00 - (_vAxis.x * _vAxis.y / _vAxis.z) * dy00 - 2.0 * _vAxis.x * dz00; - ddxdm = _vAxis.x * dy00 - (_vAxis.x * _vAxis.y / _vAxis.z) * dz00; - ddydm = _vAxis.x * dx00 + 2.0 * _vAxis.y * dy00 + (_vAxis.z - _vAxis.y * _vAxis.y / _vAxis.z) * dz00; - ddzdm = - (_vAxis.x * _vAxis.y / _vAxis.z) * dx00 + (_vAxis.z - _vAxis.y * _vAxis.y / _vAxis.z) * dy00 - 2.0 * _vAxis.y * dz00; - a[0] = -b[0]; - a[1] = -b[1]; - a[2] = 2.0 * (dx * ddxdl + dy * ddydl + dz * ddzdl); - a[3] = 2.0 * (dx * ddxdm + dy * ddydm + dz * ddzdm); - a[4] = -2.0 * _dRadius; - break; - } + // partials of the parameters + switch (solDir) { + double ddxdl, ddydl, ddzdl; + double ddxdm, ddydm, ddzdm; + double ddxdn, ddydn, ddzdn; + case solL: + // order of parameters: Yc, Zc, M, N, R + ddxdm = -2.0 * _vAxis.y * dx00 + (_vAxis.x - _vAxis.y * _vAxis.y / _vAxis.x) * dy00 + - (_vAxis.y * _vAxis.z / _vAxis.x) * dz00; + ddydm = (_vAxis.x - _vAxis.y * _vAxis.y / _vAxis.x) * dx00 + 2.0 * _vAxis.y * dy00 + + _vAxis.z * dz00; + ddzdm = -(_vAxis.y * _vAxis.z / _vAxis.x) * dx00 + _vAxis.z * dy00; + ddxdn = -2.0 * _vAxis.z * dx00 - (_vAxis.y * _vAxis.z / _vAxis.x) * dy00 + + (_vAxis.x - _vAxis.z * _vAxis.z / _vAxis.x) * dz00; + ddydn = -(_vAxis.y * _vAxis.z / _vAxis.x) * dx00 + _vAxis.y * dz00; + ddzdn = (_vAxis.x - _vAxis.z * _vAxis.z / _vAxis.x) * dx00 + _vAxis.y * dy00 + + 2.0 * _vAxis.z * dz00; + a[0] = -b[1]; + a[1] = -b[2]; + a[2] = 2.0 * (dx * ddxdm + dy * ddydm + dz * ddzdm); + a[3] = 2.0 * (dx * ddxdn + dy * ddydn + dz * ddzdn); + a[4] = -2.0 * _dRadius; + break; + case solM: + // order of parameters: Xc, Zc, L, N, R + ddxdl = 2.0 * _vAxis.x * dx00 + (_vAxis.y - _vAxis.x * _vAxis.x / _vAxis.y) * dy00 + + _vAxis.z * dz00; + ddydl = (_vAxis.y - _vAxis.x * _vAxis.x / _vAxis.y) * dx00 - 2.0 * _vAxis.x * dy00 + - (_vAxis.x * _vAxis.z / _vAxis.y) * dz00; + ddzdl = _vAxis.z * dx00 - (_vAxis.x * _vAxis.z / _vAxis.y) * dy00; + ddxdn = -(_vAxis.x * _vAxis.z / _vAxis.y) * dy00 + _vAxis.x * dz00; + ddydn = -(_vAxis.x * _vAxis.z / _vAxis.y) * dx00 - 2.0 * _vAxis.z * dy00 + + (_vAxis.y - _vAxis.z * _vAxis.z / _vAxis.y) * dz00; + ddzdn = _vAxis.x * dx00 + (_vAxis.y - _vAxis.z * _vAxis.z / _vAxis.y) * dy00 + + 2.0 * _vAxis.z * dz00; + a[0] = -b[0]; + a[1] = -b[2]; + a[2] = 2.0 * (dx * ddxdl + dy * ddydl + dz * ddzdl); + a[3] = 2.0 * (dx * ddxdn + dy * ddydn + dz * ddzdn); + a[4] = -2.0 * _dRadius; + break; + case solN: + // order of parameters: Xc, Yc, L, M, R + ddxdl = 2.0 * _vAxis.x * dx00 + _vAxis.y * dy00 + + (_vAxis.z - _vAxis.x * _vAxis.x / _vAxis.z) * dz00; + ddydl = _vAxis.y * dx00 - (_vAxis.x * _vAxis.y / _vAxis.z) * dz00; + ddzdl = (_vAxis.z - _vAxis.x * _vAxis.x / _vAxis.z) * dx00 + - (_vAxis.x * _vAxis.y / _vAxis.z) * dy00 - 2.0 * _vAxis.x * dz00; + ddxdm = _vAxis.x * dy00 - (_vAxis.x * _vAxis.y / _vAxis.z) * dz00; + ddydm = _vAxis.x * dx00 + 2.0 * _vAxis.y * dy00 + + (_vAxis.z - _vAxis.y * _vAxis.y / _vAxis.z) * dz00; + ddzdm = -(_vAxis.x * _vAxis.y / _vAxis.z) * dx00 + + (_vAxis.z - _vAxis.y * _vAxis.y / _vAxis.z) * dy00 - 2.0 * _vAxis.y * dz00; + a[0] = -b[0]; + a[1] = -b[1]; + a[2] = 2.0 * (dx * ddxdl + dy * ddydl + dz * ddzdl); + a[3] = 2.0 * (dx * ddxdm + dy * ddydm + dz * ddzdm); + a[4] = -2.0 * _dRadius; + break; + } - // free term - f0 = _dRadius * _dRadius - dx * dx - dy * dy - dz * dz + b[0] * residual.x + b[1] * residual.y + b[2] * residual.z; + // free term + f0 = _dRadius * _dRadius - dx * dx - dy * dy - dz * dz + b[0] * residual.x + b[1] * residual.y + + b[2] * residual.z; - // quasi weight (using equal weights for cylinder point coordinate observations) - //w[0] = 1.0; - //w[1] = 1.0; - //w[2] = 1.0; - //qw = 1.0 / (b[0] * b[0] / w[0] + b[1] * b[1] / w[1] + b[2] * b[2] / w[2]); - qw = 1.0 / (b[0] * b[0] + b[1] * b[1] + b[2] * b[2]); + // quasi weight (using equal weights for cylinder point coordinate observations) + // w[0] = 1.0; + // w[1] = 1.0; + // w[2] = 1.0; + // qw = 1.0 / (b[0] * b[0] / w[0] + b[1] * b[1] / w[1] + b[2] * b[2] / w[2]); + qw = 1.0 / (b[0] * b[0] + b[1] * b[1] + b[2] * b[2]); } // Computes contribution of the given observation equation on the normal equation matrices @@ -542,158 +606,174 @@ void CylinderFit::setupObservation(SolutionD solDir, const Base::Vector3f &point // pi ... weight of observation (= quasi weight qw for this solution) // atpa ... 5x5 normal equation matrix // atpl ... 5x1 matrix/vector (right-hand side of equations) -void CylinderFit::addObservationU(double a[5], double li, double pi, Matrix5x5 &atpa, Eigen::VectorXd &atpl) const +void CylinderFit::addObservationU(double a[5], + double li, + double pi, + Matrix5x5& atpa, + Eigen::VectorXd& atpl) const { - for (int i = 0; i < 5; ++i) - { - double aipi = a[i] * pi; - for (int j = i; j < 5; ++j) - { - atpa(i, j) += aipi * a[j]; - //atpa(j, i) = atpa(i, j); // it's a symmetrical matrix, we'll set this later after all observations processed - } - atpl(i) += aipi * li; - } + for (int i = 0; i < 5; ++i) { + double aipi = a[i] * pi; + for (int j = i; j < 5; ++j) { + atpa(i, j) += aipi * a[j]; + // atpa(j, i) = atpa(i, j); // it's a symmetrical matrix, we'll set this later after all + // observations processed + } + atpl(i) += aipi * li; + } } // Set the lower part of the normal matrix equal to the upper part // This is done after all the observations have been added -void CylinderFit::setLowerPart(Matrix5x5 &atpa) const +void CylinderFit::setLowerPart(Matrix5x5& atpa) const { - for (int i = 0; i < 5; ++i) - for (int j = i+1; j < 5; ++j) // skip the diagonal elements - atpa(j, i) = atpa(i, j); + for (int i = 0; i < 5; ++i) { + for (int j = i + 1; j < 5; ++j) { // skip the diagonal elements + atpa(j, i) = atpa(i, j); + } + } } // Compute the residuals and sigma0 and check the residual convergence -bool CylinderFit::computeResiduals(SolutionD solDir, const Eigen::VectorXd &x, std::vector< Base::Vector3d > &residuals, double &sigma0, double vConvLimit, bool &vConverged) const +bool CylinderFit::computeResiduals(SolutionD solDir, + const Eigen::VectorXd& x, + std::vector& residuals, + double& sigma0, + double vConvLimit, + bool& vConverged) const { - vConverged = true; - int nPtsUsed = 0; - sigma0 = 0.0; - double a[5], b[3]; - double f0, qw; - //double maxdVx = 0.0; - //double maxdVy = 0.0; - //double maxdVz = 0.0; - //double rmsVv = 0.0; - std::vector< Base::Vector3d >::iterator vIt = residuals.begin(); - std::list< Base::Vector3f >::const_iterator cIt; - for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt, ++vIt) - { - // if (using this point) { // currently all given points are used (could modify this if eliminating outliers, etc.... - ++nPtsUsed; - Base::Vector3d &v = *vIt; - setupObservation(solDir, *cIt, v, a, f0, qw, b); - double qv = -f0; - for (int i = 0; i < 5; ++i) - qv += a[i] * x(i); + vConverged = true; + int nPtsUsed = 0; + sigma0 = 0.0; + double a[5], b[3]; + double f0, qw; + // double maxdVx = 0.0; + // double maxdVy = 0.0; + // double maxdVz = 0.0; + // double rmsVv = 0.0; + std::vector::iterator vIt = residuals.begin(); + std::list::const_iterator cIt; + for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt, ++vIt) { + // if (using this point) { // currently all given points are used (could modify this if + // eliminating outliers, etc.... + ++nPtsUsed; + Base::Vector3d& v = *vIt; + setupObservation(solDir, *cIt, v, a, f0, qw, b); + double qv = -f0; + for (int i = 0; i < 5; ++i) { + qv += a[i] * x(i); + } - // We are using equal weights for cylinder point coordinate observations (see setupObservation) - // i.e. w[0] = w[1] = w[2] = 1.0; - //double vx = -qw * qv * b[0] / w[0]; - //double vy = -qw * qv * b[1] / w[1]; - //double vz = -qw * qv * b[2] / w[2]; - double vx = -qw * qv * b[0]; - double vy = -qw * qv * b[1]; - double vz = -qw * qv * b[2]; - double dVx = fabs(vx - v.x); - double dVy = fabs(vy - v.y); - double dVz = fabs(vz - v.z); - v.x = vx; - v.y = vy; - v.z = vz; + // We are using equal weights for cylinder point coordinate observations (see + // setupObservation) i.e. w[0] = w[1] = w[2] = 1.0; + // double vx = -qw * qv * b[0] / w[0]; + // double vy = -qw * qv * b[1] / w[1]; + // double vz = -qw * qv * b[2] / w[2]; + double vx = -qw * qv * b[0]; + double vy = -qw * qv * b[1]; + double vz = -qw * qv * b[2]; + double dVx = fabs(vx - v.x); + double dVy = fabs(vy - v.y); + double dVz = fabs(vz - v.z); + v.x = vx; + v.y = vy; + v.z = vz; - //double vv = v.x * v.x + v.y * v.y + v.z * v.z; - //rmsVv += vv * vv; + // double vv = v.x * v.x + v.y * v.y + v.z * v.z; + // rmsVv += vv * vv; - //sigma0 += v.x * w[0] * v.x + v.y * w[1] * v.y + v.z * w[2] * v.z; - sigma0 += v.x * v.x + v.y * v.y + v.z * v.z; + // sigma0 += v.x * w[0] * v.x + v.y * w[1] * v.y + v.z * w[2] * v.z; + sigma0 += v.x * v.x + v.y * v.y + v.z * v.z; - if ((dVx > vConvLimit) || (dVy > vConvLimit) || (dVz > vConvLimit)) - vConverged = false; + if ((dVx > vConvLimit) || (dVy > vConvLimit) || (dVz > vConvLimit)) { + vConverged = false; + } - //if (dVx > maxdVx) - // maxdVx = dVx; - //if (dVy > maxdVy) - // maxdVy = dVy; - //if (dVz > maxdVz) - // maxdVz = dVz; - } + // if (dVx > maxdVx) + // maxdVx = dVx; + // if (dVy > maxdVy) + // maxdVy = dVy; + // if (dVz > maxdVz) + // maxdVz = dVz; + } - // Compute degrees of freedom and sigma0 - if (nPtsUsed < 5) // A minimum of 5 surface points is needed to define a cylinder - { - sigma0 = 0.0; - return false; - } - int df = nPtsUsed - 5; - if (df == 0) - sigma0 = 0.0; - else - sigma0 = sqrt (sigma0 / (double)df); + // Compute degrees of freedom and sigma0 + if (nPtsUsed < 5) // A minimum of 5 surface points is needed to define a cylinder + { + sigma0 = 0.0; + return false; + } + int df = nPtsUsed - 5; + if (df == 0) { + sigma0 = 0.0; + } + else { + sigma0 = sqrt(sigma0 / (double)df); + } - //rmsVv = sqrt(rmsVv / (double)nPtsUsed); - //Base::Console().Message("X: %0.3e %0.3e %0.3e %0.3e %0.3e , Max dV: %0.4f %0.4f %0.4f , RMS Vv: %0.4f\n", x(0), x(1), x(2), x(3), x(4), maxdVx, maxdVy, maxdVz, rmsVv); + // rmsVv = sqrt(rmsVv / (double)nPtsUsed); + // Base::Console().Message("X: %0.3e %0.3e %0.3e %0.3e %0.3e , Max dV: %0.4f %0.4f %0.4f , RMS + // Vv: %0.4f\n", x(0), x(1), x(2), x(3), x(4), maxdVx, maxdVy, maxdVz, rmsVv); - return true; + return true; } // Update the parameters after solving the normal equations -bool CylinderFit::updateParameters(SolutionD solDir, const Eigen::VectorXd &x) +bool CylinderFit::updateParameters(SolutionD solDir, const Eigen::VectorXd& x) { - // Update the parameters used as unknowns in the solution - switch (solDir) - { - case solL: // order of parameters: Yc, Zc, M, N, R - _vBase.y += x(0); - _vBase.z += x(1); - _vAxis.y += x(2); - _vAxis.z += x(3); - _dRadius += x(4); - break; - case solM: // order of parameters: Xc, Zc, L, N, R - _vBase.x += x(0); - _vBase.z += x(1); - _vAxis.x += x(2); - _vAxis.z += x(3); - _dRadius += x(4); - break; - case solN: // order of parameters: Xc, Yc, L, M, R - _vBase.x += x(0); - _vBase.y += x(1); - _vAxis.x += x(2); - _vAxis.y += x(3); - _dRadius += x(4); - break; - } + // Update the parameters used as unknowns in the solution + switch (solDir) { + case solL: // order of parameters: Yc, Zc, M, N, R + _vBase.y += x(0); + _vBase.z += x(1); + _vAxis.y += x(2); + _vAxis.z += x(3); + _dRadius += x(4); + break; + case solM: // order of parameters: Xc, Zc, L, N, R + _vBase.x += x(0); + _vBase.z += x(1); + _vAxis.x += x(2); + _vAxis.z += x(3); + _dRadius += x(4); + break; + case solN: // order of parameters: Xc, Yc, L, M, R + _vBase.x += x(0); + _vBase.y += x(1); + _vAxis.x += x(2); + _vAxis.y += x(3); + _dRadius += x(4); + break; + } - // Update the dependent axis direction parameter - double l2, m2, n2; - switch (solDir) - { - case solL: - l2 = 1.0 - _vAxis.y * _vAxis.y - _vAxis.z * _vAxis.z; - if (l2 <= 0.0) - return false; // L*L <= 0 ! - _vAxis.x = sqrt(l2); - //_vBase.x is fixed - break; - case solM: - m2 = 1.0 - _vAxis.x * _vAxis.x - _vAxis.z * _vAxis.z; - if (m2 <= 0.0) - return false; // M*M <= 0 ! - _vAxis.y = sqrt(m2); - //_vBase.y is fixed - break; - case solN: - n2 = 1.0 - _vAxis.x * _vAxis.x - _vAxis.y * _vAxis.y; - if (n2 <= 0.0) - return false; // N*N <= 0 ! - _vAxis.z = sqrt(n2); - //_vBase.z is fixed - break; - } + // Update the dependent axis direction parameter + double l2, m2, n2; + switch (solDir) { + case solL: + l2 = 1.0 - _vAxis.y * _vAxis.y - _vAxis.z * _vAxis.z; + if (l2 <= 0.0) { + return false; // L*L <= 0 ! + } + _vAxis.x = sqrt(l2); + //_vBase.x is fixed + break; + case solM: + m2 = 1.0 - _vAxis.x * _vAxis.x - _vAxis.z * _vAxis.z; + if (m2 <= 0.0) { + return false; // M*M <= 0 ! + } + _vAxis.y = sqrt(m2); + //_vBase.y is fixed + break; + case solN: + n2 = 1.0 - _vAxis.x * _vAxis.x - _vAxis.y * _vAxis.y; + if (n2 <= 0.0) { + return false; // N*N <= 0 ! + } + _vAxis.z = sqrt(n2); + //_vBase.z is fixed + break; + } - return true; + return true; } diff --git a/src/Mod/Mesh/App/Core/CylinderFit.h b/src/Mod/Mesh/App/Core/CylinderFit.h index 72d3ad0bda..817c586a1a 100644 --- a/src/Mod/Mesh/App/Core/CylinderFit.h +++ b/src/Mod/Mesh/App/Core/CylinderFit.h @@ -29,22 +29,26 @@ // ------------------------------------------------------------------------------- -namespace MeshCoreFit { +namespace MeshCoreFit +{ -using Matrix5x5 = Eigen::Matrix; +using Matrix5x5 = Eigen::Matrix; /** * Best-fit cylinder for a given set of points. * Doesn't expect points on any top or bottom end-planes, only points on the side surface */ -class MeshExport CylinderFit : public MeshCore::Approximation +class MeshExport CylinderFit: public MeshCore::Approximation { protected: - // Solution 'direction' enumeration - enum SolutionD {solL = 0, // solution L: L is biggest axis component and L = f(M,N) - solM = 1, // solution M: M is biggest axis component and M = f(L,N) - solN = 2 // solution N: N is biggest axis component and N = f(L,M) - }; + // Solution 'direction' enumeration + enum SolutionD + { + solL = 0, // solution L: L is biggest axis component and L = f(M,N) + solM = 1, // solution M: M is biggest axis component and M = f(L,N) + solN = 2 // solution N: N is biggest axis component and N = f(L,M) + }; + public: /** * Construction @@ -53,33 +57,40 @@ public: /** * Set approximations before calling Fit() */ - void SetApproximations(double radius, const Base::Vector3d &base, const Base::Vector3d &axis); + void SetApproximations(double radius, const Base::Vector3d& base, const Base::Vector3d& axis); /** * Set approximations before calling Fit(). This version computes the radius - * using the given axis and the existing surface points. + * using the given axis and the existing surface points. */ - void SetApproximations(const Base::Vector3d &base, const Base::Vector3d &axis); + void SetApproximations(const Base::Vector3d& base, const Base::Vector3d& axis); /** - * Set iteration convergence criteria for the fit if special values are needed. - * The default values set in the constructor are suitable for most uses + * Set iteration convergence criteria for the fit if special values are needed. + * The default values set in the constructor are suitable for most uses */ - void SetConvergenceCriteria(double posConvLimit, double dirConvLimit, double vConvLimit, int maxIter); + void SetConvergenceCriteria(double posConvLimit, + double dirConvLimit, + double vConvLimit, + int maxIter); /** - * Returns the radius of the fitted cylinder. If Fit() has not been called then zero is returned. + * Returns the radius of the fitted cylinder. If Fit() has not been called then zero is + * returned. */ double GetRadius() const; /** - * Returns the base of the fitted cylinder. If Fit() has not been called the null vector is returned. + * Returns the base of the fitted cylinder. If Fit() has not been called the null vector is + * returned. */ Base::Vector3d GetBase() const; /** - * Returns the axis of the fitted cylinder. If Fit() has not been called the null vector is returned. + * Returns the axis of the fitted cylinder. If Fit() has not been called the null vector is + * returned. */ Base::Vector3d GetAxis() const; /** - * Returns the number of iterations that Fit() needed to converge. If Fit() has not been called then zero is returned. + * Returns the number of iterations that Fit() needed to converge. If Fit() has not been called + * then zero is returned. */ - int GetNumIterations() const; + int GetNumIterations() const; /** * Fit a cylinder into the given points. If the fit fails FLOAT_MAX is returned. */ @@ -88,7 +99,7 @@ public: * Returns the distance from the point \a rcPoint to the fitted cylinder. If Fit() has not been * called FLOAT_MAX is returned. */ - float GetDistanceToCylinder(const Base::Vector3f &rcPoint) const; + float GetDistanceToCylinder(const Base::Vector3f& rcPoint) const; /** * Returns the standard deviation from the points to the fitted cylinder. If Fit() has not been * called FLOAT_MAX is returned. @@ -101,64 +112,81 @@ public: protected: /** - * Compute approximations for the parameters using all points using the line fit method + * Compute approximations for the parameters using all points using the line fit method */ - void ComputeApproximationsLine(); - /** - * Checks initial parameter values and defines the best solution direction to use - */ - void findBestSolDirection(SolutionD &solDir); + void ComputeApproximationsLine(); /** - * Compute the mean X-value of all of the points (observed/input surface points) + * Checks initial parameter values and defines the best solution direction to use */ - double meanXObs(); + void findBestSolDirection(SolutionD& solDir); /** - * Compute the mean Y-value of all of the points (observed/input surface points) + * Compute the mean X-value of all of the points (observed/input surface points) */ - double meanYObs(); + double meanXObs(); /** - * Compute the mean Z-value of all of the points (observed/input surface points) + * Compute the mean Y-value of all of the points (observed/input surface points) */ - double meanZObs(); - /** - * Set up the normal equations + double meanYObs(); + /** + * Compute the mean Z-value of all of the points (observed/input surface points) */ - void setupNormalEquationMatrices(SolutionD solDir, const std::vector< Base::Vector3d > &residuals, Matrix5x5 &atpa, Eigen::VectorXd &atpl) const; - /** - * Sets up contributions of given observation to the normal equation matrices. + double meanZObs(); + /** + * Set up the normal equations */ - void setupObservation(SolutionD solDir, const Base::Vector3f &point, const Base::Vector3d &residual, double a[5], double &f0, double &qw, double b[3]) const; - /** - * Computes contribution of the given observation equation on the normal equation matrices + void setupNormalEquationMatrices(SolutionD solDir, + const std::vector& residuals, + Matrix5x5& atpa, + Eigen::VectorXd& atpl) const; + /** + * Sets up contributions of given observation to the normal equation matrices. */ - void addObservationU(double a[5], double li, double pi, Matrix5x5 &atpa, Eigen::VectorXd &atpl) const; - /** - * Set the lower part of the normal matrix equal to the upper part + void setupObservation(SolutionD solDir, + const Base::Vector3f& point, + const Base::Vector3d& residual, + double a[5], + double& f0, + double& qw, + double b[3]) const; + /** + * Computes contribution of the given observation equation on the normal equation matrices */ - void setLowerPart(Matrix5x5 &atpa) const; + void addObservationU(double a[5], + double li, + double pi, + Matrix5x5& atpa, + Eigen::VectorXd& atpl) const; + /** + * Set the lower part of the normal matrix equal to the upper part + */ + void setLowerPart(Matrix5x5& atpa) const; - /** - * Compute the residuals and sigma0 and check the residual convergence + /** + * Compute the residuals and sigma0 and check the residual convergence */ - bool computeResiduals(SolutionD solDir, const Eigen::VectorXd &x, std::vector< Base::Vector3d > &residuals, double &sigma0, double vConvLimit, bool &vConverged) const; - /** - * Update the parameters after solving the normal equations + bool computeResiduals(SolutionD solDir, + const Eigen::VectorXd& x, + std::vector& residuals, + double& sigma0, + double vConvLimit, + bool& vConverged) const; + /** + * Update the parameters after solving the normal equations */ - bool updateParameters(SolutionD solDir, const Eigen::VectorXd &x); + bool updateParameters(SolutionD solDir, const Eigen::VectorXd& x); private: - Base::Vector3d _vBase; /**< Base vector of the cylinder (point on axis). */ - Base::Vector3d _vAxis; /**< Axis of the cylinder. */ - double _dRadius{0}; /**< Radius of the cylinder. */ - int _numIter{0}; /**< Number of iterations for solution to converge. */ - double _posConvLimit{0.0001}; /**< Position and radius parameter convergence threshold. */ - double _dirConvLimit{0.000001}; /**< Direction parameter convergence threshold. */ - double _vConvLimit{0.001}; /**< Residual convergence threshold. */ - int _maxIter{50}; /**< Maximum number of iterations. */ - + Base::Vector3d _vBase; /**< Base vector of the cylinder (point on axis). */ + Base::Vector3d _vAxis; /**< Axis of the cylinder. */ + double _dRadius {0}; /**< Radius of the cylinder. */ + int _numIter {0}; /**< Number of iterations for solution to converge. */ + double _posConvLimit {0.0001}; /**< Position and radius parameter convergence threshold. */ + double _dirConvLimit {0.000001}; /**< Direction parameter convergence threshold. */ + double _vConvLimit {0.001}; /**< Residual convergence threshold. */ + int _maxIter {50}; /**< Maximum number of iterations. */ }; -} // namespace MeshCore +} // namespace MeshCoreFit -#endif // MESH_CYLINDER_FIT_H +#endif // MESH_CYLINDER_FIT_H diff --git a/src/Mod/Mesh/App/Core/Decimation.cpp b/src/Mod/Mesh/App/Core/Decimation.cpp index 210f621d52..b9d0a2389a 100644 --- a/src/Mod/Mesh/App/Core/Decimation.cpp +++ b/src/Mod/Mesh/App/Core/Decimation.cpp @@ -30,9 +30,8 @@ using namespace MeshCore; MeshSimplify::MeshSimplify(MeshKernel& mesh) - : myKernel(mesh) -{ -} + : myKernel(mesh) +{} void MeshSimplify::simplify(float tolerance, float reduction) { @@ -53,14 +52,16 @@ void MeshSimplify::simplify(float tolerance, float reduction) Simplify::Triangle t; t.deleted = 0; t.dirty = 0; - for (double & j : t.err) + for (double& j : t.err) { j = 0.0; - for (int j = 0; j < 3; j++) + } + for (int j = 0; j < 3; j++) { t.v[j] = facets[i]._aulPoints[j]; + } alg.triangles.push_back(t); } - int target_count = static_cast(static_cast(facets.size()) * (1.0f-reduction)); + int target_count = static_cast(static_cast(facets.size()) * (1.0f - reduction)); // Simplification starts alg.simplify_mesh(target_count, tolerance); @@ -68,18 +69,19 @@ void MeshSimplify::simplify(float tolerance, float reduction) // Simplification done MeshPointArray new_points; new_points.reserve(alg.vertices.size()); - for (const auto & vertex : alg.vertices) { + for (const auto& vertex : alg.vertices) { new_points.push_back(vertex.p); } std::size_t numFacets = 0; - for (const auto & triangle : alg.triangles) { - if (!triangle.deleted) + for (const auto& triangle : alg.triangles) { + if (!triangle.deleted) { numFacets++; + } } MeshFacetArray new_facets; new_facets.reserve(numFacets); - for (const auto & triangle : alg.triangles) { + for (const auto& triangle : alg.triangles) { if (!triangle.deleted) { MeshFacet face; face._aulPoints[0] = triangle.v[0]; @@ -111,10 +113,12 @@ void MeshSimplify::simplify(int targetSize) Simplify::Triangle t; t.deleted = 0; t.dirty = 0; - for (double & j : t.err) + for (double& j : t.err) { j = 0.0; - for (int j = 0; j < 3; j++) + } + for (int j = 0; j < 3; j++) { t.v[j] = facets[i]._aulPoints[j]; + } alg.triangles.push_back(t); } @@ -124,18 +128,19 @@ void MeshSimplify::simplify(int targetSize) // Simplification done MeshPointArray new_points; new_points.reserve(alg.vertices.size()); - for (const auto & vertex : alg.vertices) { + for (const auto& vertex : alg.vertices) { new_points.push_back(vertex.p); } std::size_t numFacets = 0; - for (const auto & triangle : alg.triangles) { - if (!triangle.deleted) + for (const auto& triangle : alg.triangles) { + if (!triangle.deleted) { numFacets++; + } } MeshFacetArray new_facets; new_facets.reserve(numFacets); - for (const auto & triangle : alg.triangles) { + for (const auto& triangle : alg.triangles) { if (!triangle.deleted) { MeshFacet face; face._aulPoints[0] = triangle.v[0]; diff --git a/src/Mod/Mesh/App/Core/Decimation.h b/src/Mod/Mesh/App/Core/Decimation.h index cad05356a6..ba19bfd9cb 100644 --- a/src/Mod/Mesh/App/Core/Decimation.h +++ b/src/Mod/Mesh/App/Core/Decimation.h @@ -33,7 +33,7 @@ class MeshKernel; class MeshExport MeshSimplify { public: - MeshSimplify(MeshKernel&);//explicit bombs + MeshSimplify(MeshKernel&); // explicit bombs void simplify(float tolerance, float reduction); void simplify(int targetSize); @@ -41,7 +41,7 @@ private: MeshKernel& myKernel; }; -} // namespace MeshCore +} // namespace MeshCore #endif // MESH_DECIMATION_H diff --git a/src/Mod/Mesh/App/Core/Definitions.cpp b/src/Mod/Mesh/App/Core/Definitions.cpp index dc99816a62..ff8882c399 100644 --- a/src/Mod/Mesh/App/Core/Definitions.cpp +++ b/src/Mod/Mesh/App/Core/Definitions.cpp @@ -24,29 +24,32 @@ #include -#include #include "Definitions.h" +#include -namespace MeshCore { - -template<> MeshExport const float Math ::PI = (float)(4.0*atan(1.0)); -template<> MeshExport const double Math::PI = 4.0*atan(1.0); - -float MeshDefinitions::_fMinPointDistance = float(MESH_MIN_PT_DIST); -float MeshDefinitions::_fMinPointDistanceP2 = _fMinPointDistance * _fMinPointDistance; -float MeshDefinitions::_fMinPointDistanceD1 = _fMinPointDistance; -float MeshDefinitions::_fMinEdgeLength = MESH_MIN_EDGE_LEN; -bool MeshDefinitions::_bRemoveMinLength = MESH_REMOVE_MIN_LEN; -float MeshDefinitions::_fMinEdgeAngle = Base::toRadians(MESH_MIN_EDGE_ANGLE); - -MeshDefinitions::MeshDefinitions () = default; - -void MeshDefinitions::SetMinPointDistance (float fMin) +namespace MeshCore { - _fMinPointDistance = fMin; - _fMinPointDistanceP2 = fMin * fMin; - _fMinPointDistanceD1 = float(sqrt((fMin * fMin) / 3.0f)); + +template<> +MeshExport const float Math::PI = (float)(4.0 * atan(1.0)); +template<> +MeshExport const double Math::PI = 4.0 * atan(1.0); + +float MeshDefinitions::_fMinPointDistance = float(MESH_MIN_PT_DIST); +float MeshDefinitions::_fMinPointDistanceP2 = _fMinPointDistance * _fMinPointDistance; +float MeshDefinitions::_fMinPointDistanceD1 = _fMinPointDistance; +float MeshDefinitions::_fMinEdgeLength = MESH_MIN_EDGE_LEN; +bool MeshDefinitions::_bRemoveMinLength = MESH_REMOVE_MIN_LEN; +float MeshDefinitions::_fMinEdgeAngle = Base::toRadians(MESH_MIN_EDGE_ANGLE); + +MeshDefinitions::MeshDefinitions() = default; + +void MeshDefinitions::SetMinPointDistance(float fMin) +{ + _fMinPointDistance = fMin; + _fMinPointDistanceP2 = fMin * fMin; + _fMinPointDistanceD1 = float(sqrt((fMin * fMin) / 3.0f)); } -} +} // namespace MeshCore diff --git a/src/Mod/Mesh/App/Core/Definitions.h b/src/Mod/Mesh/App/Core/Definitions.h index d1ef6ab329..9337ab396e 100644 --- a/src/Mod/Mesh/App/Core/Definitions.h +++ b/src/Mod/Mesh/App/Core/Definitions.h @@ -24,16 +24,16 @@ #define MESH_DEFINITIONS_H #ifndef MESH_GLOBAL_H -# include +#include #endif #include // default values -#define MESH_MIN_PT_DIST 1.0e-6f -#define MESH_MIN_EDGE_LEN 1.0e-3f -#define MESH_MIN_EDGE_ANGLE 2.0 -#define MESH_REMOVE_MIN_LEN true +#define MESH_MIN_PT_DIST 1.0e-6f +#define MESH_MIN_EDGE_LEN 1.0e-3f +#define MESH_MIN_EDGE_ANGLE 2.0 +#define MESH_REMOVE_MIN_LEN true #define MESH_REMOVE_G3_EDGES true /* @@ -41,19 +41,20 @@ */ #define FLOAT_EPS 1.0e-4f -#ifndef FLOAT_MAX -# define FLOAT_MAX 1e30f +#ifndef FLOAT_MAX +#define FLOAT_MAX 1e30f #endif -#ifndef DOUBLE_MAX -# define DOUBLE_MAX 1.7976931348623157E+308 /* max decimal value of a "double"*/ +#ifndef DOUBLE_MAX +#define DOUBLE_MAX 1.7976931348623157E+308 /* max decimal value of a "double"*/ #endif -#ifndef DOUBLE_MIN -# define DOUBLE_MIN 2.2250738585072014E-308 /* min decimal value of a "double"*/ +#ifndef DOUBLE_MIN +#define DOUBLE_MIN 2.2250738585072014E-308 /* min decimal value of a "double"*/ #endif -namespace MeshCore { +namespace MeshCore +{ // type definitions using ElementIndex = unsigned long; @@ -63,7 +64,7 @@ const FacetIndex FACET_INDEX_MAX = ULONG_MAX; using PointIndex = ElementIndex; const PointIndex POINT_INDEX_MAX = ULONG_MAX; -template +template class Math { public: @@ -80,20 +81,20 @@ using Mathd = Math; class MeshExport MeshDefinitions { public: - MeshDefinitions (); + MeshDefinitions(); - static float _fMinPointDistance; - static float _fMinPointDistanceP2; - static float _fMinPointDistanceD1; + static float _fMinPointDistance; + static float _fMinPointDistanceP2; + static float _fMinPointDistanceD1; - static float _fMinEdgeLength; - static bool _bRemoveMinLength; + static float _fMinEdgeLength; + static bool _bRemoveMinLength; - static float _fMinEdgeAngle; + static float _fMinEdgeAngle; - static void SetMinPointDistance (float fMin); + static void SetMinPointDistance(float fMin); }; -} // namespace MeshCore +} // namespace MeshCore -#endif // MESH_DEFINITIONS_H +#endif // MESH_DEFINITIONS_H diff --git a/src/Mod/Mesh/App/Core/Degeneration.cpp b/src/Mod/Mesh/App/Core/Degeneration.cpp index 033ad2beef..9f00419996 100644 --- a/src/Mod/Mesh/App/Core/Degeneration.cpp +++ b/src/Mod/Mesh/App/Core/Degeneration.cpp @@ -23,9 +23,9 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include +#include +#include +#include #endif #include @@ -41,53 +41,57 @@ using namespace MeshCore; bool MeshEvalInvalids::Evaluate() { - const MeshFacetArray& rFaces = _rclMesh.GetFacets(); - for (const auto & it : rFaces) - { - if ( !it.IsValid() ) - return false; - } + const MeshFacetArray& rFaces = _rclMesh.GetFacets(); + for (const auto& it : rFaces) { + if (!it.IsValid()) { + return false; + } + } - const MeshPointArray& rPoints = _rclMesh.GetPoints(); - for (const auto & it : rPoints) - { - if ( !it.IsValid() ) - return false; - } + const MeshPointArray& rPoints = _rclMesh.GetPoints(); + for (const auto& it : rPoints) { + if (!it.IsValid()) { + return false; + } + } - return true; + return true; } std::vector MeshEvalInvalids::GetIndices() const { - std::vector aInds; - const MeshFacetArray& rFaces = _rclMesh.GetFacets(); - const MeshPointArray& rPoints = _rclMesh.GetPoints(); - FacetIndex ind=0; - for ( MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, ind++ ) - { - if ( !it->IsValid() ) - aInds.push_back(ind); - else if ( !rPoints[it->_aulPoints[0]].IsValid() ) - aInds.push_back(ind); - else if ( !rPoints[it->_aulPoints[1]].IsValid() ) - aInds.push_back(ind); - else if ( !rPoints[it->_aulPoints[2]].IsValid() ) - aInds.push_back(ind); - } + std::vector aInds; + const MeshFacetArray& rFaces = _rclMesh.GetFacets(); + const MeshPointArray& rPoints = _rclMesh.GetPoints(); + FacetIndex ind = 0; + for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, ind++) { + if (!it->IsValid()) { + aInds.push_back(ind); + } + else if (!rPoints[it->_aulPoints[0]].IsValid()) { + aInds.push_back(ind); + } + else if (!rPoints[it->_aulPoints[1]].IsValid()) { + aInds.push_back(ind); + } + else if (!rPoints[it->_aulPoints[2]].IsValid()) { + aInds.push_back(ind); + } + } - return aInds; + return aInds; } bool MeshFixInvalids::Fixup() { - _rclMesh.RemoveInvalids(); - return true; + _rclMesh.RemoveInvalids(); + return true; } // ---------------------------------------------------------------------- -namespace MeshCore { +namespace MeshCore +{ using VertexIterator = MeshPointArray::_TConstIterator; /* @@ -99,27 +103,27 @@ using VertexIterator = MeshPointArray::_TConstIterator; */ struct Vertex_EqualTo { - bool operator()(const VertexIterator& x, - const VertexIterator& y) const + bool operator()(const VertexIterator& x, const VertexIterator& y) const { - if ( (*x) < (*y) ) + if ((*x) < (*y)) { return false; - else if ( (*y) < (*x) ) + } + else if ((*y) < (*x)) { return false; + } return true; } }; struct Vertex_Less { - bool operator()(const VertexIterator& x, - const VertexIterator& y) const + bool operator()(const VertexIterator& x, const VertexIterator& y) const { return (*x) < (*y); } }; -} +} // namespace MeshCore bool MeshEvalDuplicatePoints::Evaluate() { @@ -134,16 +138,17 @@ bool MeshEvalDuplicatePoints::Evaluate() // if there are two adjacent vertices which have the same coordinates std::sort(vertices.begin(), vertices.end(), Vertex_Less()); - if (std::adjacent_find(vertices.begin(), vertices.end(), Vertex_EqualTo()) < vertices.end() ) + if (std::adjacent_find(vertices.begin(), vertices.end(), Vertex_EqualTo()) < vertices.end()) { return false; + } return true; } std::vector MeshEvalDuplicatePoints::GetIndices() const { - //Note: We must neither use map or set to get duplicated indices because - //the sort algorithms deliver different results compared to std::sort of - //a vector. + // Note: We must neither use map or set to get duplicated indices because + // the sort algorithms deliver different results compared to std::sort of + // a vector. const MeshPointArray& rPoints = _rclMesh.GetPoints(); std::vector vertices; vertices.reserve(rPoints.size()); @@ -171,9 +176,9 @@ std::vector MeshEvalDuplicatePoints::GetIndices() const bool MeshFixDuplicatePoints::Fixup() { - //Note: We must neither use map or set to get duplicated indices because - //the sort algorithms deliver different results compared to std::sort of - //a vector. + // Note: We must neither use map or set to get duplicated indices because + // the sort algorithms deliver different results compared to std::sort of + // a vector. const MeshPointArray& rPoints = _rclMesh.GetPoints(); std::vector vertices; vertices.reserve(rPoints.size()); @@ -205,11 +210,12 @@ bool MeshFixDuplicatePoints::Fixup() // now set all facets to the correct index MeshFacetArray& rFacets = _rclMesh._aclFacetArray; - for (auto & it : rFacets) { - for (PointIndex & point : it._aulPoints) { + for (auto& it : rFacets) { + for (PointIndex& point : it._aulPoints) { std::map::iterator pt = mapPointIndex.find(point); - if (pt != mapPointIndex.end()) + if (pt != mapPointIndex.end()) { point = pt->second; + } } } @@ -225,9 +231,10 @@ bool MeshFixDuplicatePoints::Fixup() bool MeshEvalNaNPoints::Evaluate() { const MeshPointArray& rPoints = _rclMesh.GetPoints(); - for (const auto & it : rPoints) { - if (boost::math::isnan(it.x) || boost::math::isnan(it.y) || boost::math::isnan(it.z)) + for (const auto& it : rPoints) { + if (boost::math::isnan(it.x) || boost::math::isnan(it.y) || boost::math::isnan(it.z)) { return false; + } } return true; @@ -238,8 +245,9 @@ std::vector MeshEvalNaNPoints::GetIndices() const std::vector aInds; const MeshPointArray& rPoints = _rclMesh.GetPoints(); for (MeshPointArray::_TConstIterator it = rPoints.begin(); it != rPoints.end(); ++it) { - if (boost::math::isnan(it->x) || boost::math::isnan(it->y) || boost::math::isnan(it->z)) + if (boost::math::isnan(it->x) || boost::math::isnan(it->y) || boost::math::isnan(it->z)) { aInds.push_back(it - rPoints.begin()); + } } return aInds; @@ -250,8 +258,9 @@ bool MeshFixNaNPoints::Fixup() std::vector aInds; const MeshPointArray& rPoints = _rclMesh.GetPoints(); for (MeshPointArray::_TConstIterator it = rPoints.begin(); it != rPoints.end(); ++it) { - if (boost::math::isnan(it->x) || boost::math::isnan(it->y) || boost::math::isnan(it->z)) + if (boost::math::isnan(it->x) || boost::math::isnan(it->y) || boost::math::isnan(it->z)) { aInds.push_back(it - rPoints.begin()); + } } // remove invalid indices @@ -263,7 +272,8 @@ bool MeshFixNaNPoints::Fixup() // ---------------------------------------------------------------------- -namespace MeshCore { +namespace MeshCore +{ using FaceIterator = MeshFacetArray::_TConstIterator; /* @@ -271,8 +281,7 @@ using FaceIterator = MeshFacetArray::_TConstIterator; */ struct MeshFacet_Less { - bool operator()(const FaceIterator& x, - const FaceIterator& y) const + bool operator()(const FaceIterator& x, const FaceIterator& y) const { PointIndex tmp; PointIndex x0 = x->_aulPoints[0]; @@ -282,35 +291,59 @@ struct MeshFacet_Less PointIndex y1 = y->_aulPoints[1]; PointIndex y2 = y->_aulPoints[2]; - if (x0 > x1) - { tmp = x0; x0 = x1; x1 = tmp; } - if (x0 > x2) - { tmp = x0; x0 = x2; x2 = tmp; } - if (x1 > x2) - { tmp = x1; x1 = x2; x2 = tmp; } - if (y0 > y1) - { tmp = y0; y0 = y1; y1 = tmp; } - if (y0 > y2) - { tmp = y0; y0 = y2; y2 = tmp; } - if (y1 > y2) - { tmp = y1; y1 = y2; y2 = tmp; } + if (x0 > x1) { + tmp = x0; + x0 = x1; + x1 = tmp; + } + if (x0 > x2) { + tmp = x0; + x0 = x2; + x2 = tmp; + } + if (x1 > x2) { + tmp = x1; + x1 = x2; + x2 = tmp; + } + if (y0 > y1) { + tmp = y0; + y0 = y1; + y1 = tmp; + } + if (y0 > y2) { + tmp = y0; + y0 = y2; + y2 = tmp; + } + if (y1 > y2) { + tmp = y1; + y1 = y2; + y2 = tmp; + } - if (x0 < y0) + if (x0 < y0) { return true; - else if (x0 > y0) + } + else if (x0 > y0) { return false; - else if (x1 < y1) + } + else if (x1 < y1) { return true; - else if (x1 > y1) + } + else if (x1 > y1) { return false; - else if (x2 < y2) + } + else if (x2 < y2) { return true; - else + } + else { return false; + } } }; -} +} // namespace MeshCore /* * Two facets are equal if all its three point indices refer to the same @@ -318,17 +351,18 @@ struct MeshFacet_Less */ struct MeshFacet_EqualTo { - bool operator()(const FaceIterator& x, - const FaceIterator& y) const + bool operator()(const FaceIterator& x, const FaceIterator& y) const { - for (int i=0; i<3; i++ ) { + for (int i = 0; i < 3; i++) { if (x->_aulPoints[0] == y->_aulPoints[i]) { - if (x->_aulPoints[1] == y->_aulPoints[(i+1)%3] && - x->_aulPoints[2] == y->_aulPoints[(i+2)%3]) + if (x->_aulPoints[1] == y->_aulPoints[(i + 1) % 3] + && x->_aulPoints[2] == y->_aulPoints[(i + 2) % 3]) { return true; - else if (x->_aulPoints[1] == y->_aulPoints[(i+2)%3] && - x->_aulPoints[2] == y->_aulPoints[(i+1)%3]) + } + else if (x->_aulPoints[1] == y->_aulPoints[(i + 2) % 3] + && x->_aulPoints[2] == y->_aulPoints[(i + 1) % 3]) { return true; + } } } @@ -338,17 +372,16 @@ struct MeshFacet_EqualTo bool MeshEvalDuplicateFacets::Evaluate() { - std::set aFaces; - const MeshFacetArray& rFaces = _rclMesh.GetFacets(); - for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it) - { - std::pair::iterator, bool> - pI = aFaces.insert(it); - if (!pI.second) - return false; - } + std::set aFaces; + const MeshFacetArray& rFaces = _rclMesh.GetFacets(); + for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it) { + std::pair::iterator, bool> pI = aFaces.insert(it); + if (!pI.second) { + return false; + } + } - return true; + return true; } std::vector MeshEvalDuplicateFacets::GetIndices() const @@ -378,41 +411,40 @@ std::vector MeshEvalDuplicateFacets::GetIndices() const return aInds; #else - std::vector aInds; - const MeshFacetArray& rFaces = _rclMesh.GetFacets(); - FacetIndex uIndex=0; + std::vector aInds; + const MeshFacetArray& rFaces = _rclMesh.GetFacets(); + FacetIndex uIndex = 0; - // get all facets - std::set aFaceSet; - for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, uIndex++) - { - std::pair::iterator, bool> - pI = aFaceSet.insert(it); - if (!pI.second) - aInds.push_back(uIndex); - } + // get all facets + std::set aFaceSet; + for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, uIndex++) { + std::pair::iterator, bool> pI = aFaceSet.insert(it); + if (!pI.second) { + aInds.push_back(uIndex); + } + } - return aInds; + return aInds; #endif } bool MeshFixDuplicateFacets::Fixup() { - FacetIndex uIndex=0; + FacetIndex uIndex = 0; std::vector aRemoveFaces; const MeshFacetArray& rFaces = _rclMesh.GetFacets(); // get all facets - std::set aFaceSet; + std::set aFaceSet; for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, uIndex++) { - std::pair::iterator, bool> - pI = aFaceSet.insert(it); - if (!pI.second) + std::pair::iterator, bool> pI = aFaceSet.insert(it); + if (!pI.second) { aRemoveFaces.push_back(uIndex); + } } _rclMesh.DeleteFacets(aRemoveFaces); - _rclMesh.RebuildNeighbours(); // needs to be done here + _rclMesh.RebuildNeighbours(); // needs to be done here return true; } @@ -422,15 +454,14 @@ bool MeshFixDuplicateFacets::Fixup() bool MeshEvalInternalFacets::Evaluate() { _indices.clear(); - FacetIndex uIndex=0; + FacetIndex uIndex = 0; const MeshFacetArray& rFaces = _rclMesh.GetFacets(); // get all facets - std::set aFaceSet; + std::set aFaceSet; MeshFacetArray::_TConstIterator first = rFaces.begin(); for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, uIndex++) { - std::pair::iterator, bool> - pI = aFaceSet.insert(it); + std::pair::iterator, bool> pI = aFaceSet.insert(it); if (!pI.second) { // collect both elements _indices.push_back(*pI.first - first); @@ -447,22 +478,25 @@ bool MeshEvalDegeneratedFacets::Evaluate() { MeshFacetIterator it(_rclMesh); for (it.Init(); it.More(); it.Next()) { - if (it->IsDegenerated(fEpsilon)) + if (it->IsDegenerated(fEpsilon)) { return false; + } } return true; } -unsigned long MeshEvalDegeneratedFacets::CountEdgeTooSmall (float fMinEdgeLength) const +unsigned long MeshEvalDegeneratedFacets::CountEdgeTooSmall(float fMinEdgeLength) const { - MeshFacetIterator clFIter(_rclMesh); + MeshFacetIterator clFIter(_rclMesh); unsigned long k = 0; while (!clFIter.EndReached()) { for (int i = 0; i < 3; i++) { - if (Base::Distance(clFIter->_aclPoints[i], clFIter->_aclPoints[(i+1)%3]) < fMinEdgeLength) + if (Base::Distance(clFIter->_aclPoints[i], clFIter->_aclPoints[(i + 1) % 3]) + < fMinEdgeLength) { k++; + } } ++clFIter; } @@ -475,8 +509,9 @@ std::vector MeshEvalDegeneratedFacets::GetIndices() const std::vector aInds; MeshFacetIterator it(_rclMesh); for (it.Init(); it.More(); it.Next()) { - if (it->IsDegenerated(fEpsilon)) + if (it->IsDegenerated(fEpsilon)) { aInds.push_back(it.Position()); + } } return aInds; @@ -493,7 +528,7 @@ bool MeshFixDegeneratedFacets::Fixup() bool removed = cTopAlg.RemoveDegeneratedFacet(uId); if (removed) { // due to a modification of the array the iterator became invalid - it.Set(uId-1); + it.Set(uId - 1); } } } @@ -503,29 +538,27 @@ bool MeshFixDegeneratedFacets::Fixup() bool MeshRemoveNeedles::Fixup() { - using FaceEdge = std::pair; // (face, edge) pair + using FaceEdge = std::pair; // (face, edge) pair using FaceEdgePriority = std::pair; MeshTopoAlgorithm topAlg(_rclMesh); MeshRefPointToFacets vf_it(_rclMesh); - const MeshFacetArray &rclFAry = _rclMesh.GetFacets(); - const MeshPointArray &rclPAry = _rclMesh.GetPoints(); + const MeshFacetArray& rclFAry = _rclMesh.GetFacets(); + const MeshPointArray& rclPAry = _rclMesh.GetPoints(); rclFAry.ResetInvalid(); rclPAry.ResetInvalid(); rclPAry.ResetFlag(MeshPoint::VISIT); std::size_t facetCount = rclFAry.size(); - std::priority_queue, - std::greater<> > todo; + std::priority_queue, std::greater<>> todo; for (std::size_t index = 0; index < facetCount; index++) { const MeshFacet& facet = rclFAry[index]; MeshGeomFacet tria(_rclMesh.GetFacet(facet)); float perimeter = tria.Perimeter(); float fMinLen = perimeter * fMinEdgeLength; - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { const Base::Vector3f& p1 = rclPAry[facet._aulPoints[i]]; - const Base::Vector3f& p2 = rclPAry[facet._aulPoints[(i+1)%3]]; + const Base::Vector3f& p2 = rclPAry[facet._aulPoints[(i + 1) % 3]]; float distance = Base::Distance(p1, p2); if (distance < fMinLen) { @@ -541,8 +574,9 @@ bool MeshRemoveNeedles::Fixup() todo.pop(); // check if one of the face pairs was already processed - if (!rclFAry[faceedge.first].IsValid()) + if (!rclFAry[faceedge.first].IsValid()) { continue; + } // the facet points may have changed, so check the current distance again const MeshFacet& facet = rclFAry[faceedge.first]; @@ -550,33 +584,36 @@ bool MeshRemoveNeedles::Fixup() float perimeter = tria.Perimeter(); float fMinLen = perimeter * fMinEdgeLength; const Base::Vector3f& p1 = rclPAry[facet._aulPoints[faceedge.second]]; - const Base::Vector3f& p2 = rclPAry[facet._aulPoints[(faceedge.second+1)%3]]; + const Base::Vector3f& p2 = rclPAry[facet._aulPoints[(faceedge.second + 1) % 3]]; float distance = Base::Distance(p1, p2); - if (distance >= fMinLen) + if (distance >= fMinLen) { continue; + } // collect the collapse-edge information EdgeCollapse ce; ce._fromPoint = rclFAry[faceedge.first]._aulPoints[faceedge.second]; - ce._toPoint = rclFAry[faceedge.first]._aulPoints[(faceedge.second+1)%3]; + ce._toPoint = rclFAry[faceedge.first]._aulPoints[(faceedge.second + 1) % 3]; ce._removeFacets.push_back(faceedge.first); FacetIndex neighbour = rclFAry[faceedge.first]._aulNeighbours[faceedge.second]; - if (neighbour != FACET_INDEX_MAX) + if (neighbour != FACET_INDEX_MAX) { ce._removeFacets.push_back(neighbour); + } std::set vf = vf_it[ce._fromPoint]; vf.erase(faceedge.first); - if (neighbour != FACET_INDEX_MAX) + if (neighbour != FACET_INDEX_MAX) { vf.erase(neighbour); + } ce._changeFacets.insert(ce._changeFacets.begin(), vf.begin(), vf.end()); // get adjacent points std::set vv; vv = vf_it.NeighbourPoints(ce._fromPoint); - ce._adjacentFrom.insert(ce._adjacentFrom.begin(), vv.begin(),vv.end()); + ce._adjacentFrom.insert(ce._adjacentFrom.begin(), vv.begin(), vv.end()); vv = vf_it.NeighbourPoints(ce._toPoint); - ce._adjacentTo.insert(ce._adjacentTo.begin(), vv.begin(),vv.end()); + ce._adjacentTo.insert(ce._adjacentTo.begin(), vv.begin(), vv.end()); if (topAlg.IsCollapseEdgeLegal(ce)) { topAlg.CollapseEdge(ce); @@ -603,27 +640,27 @@ bool MeshRemoveNeedles::Fixup() bool MeshFixCaps::Fixup() { - using FaceVertex = std::pair; // (face, vertex) pair + using FaceVertex = std::pair; // (face, vertex) pair using FaceVertexPriority = std::pair; MeshTopoAlgorithm topAlg(_rclMesh); - const MeshFacetArray &rclFAry = _rclMesh.GetFacets(); - const MeshPointArray &rclPAry = _rclMesh.GetPoints(); + const MeshFacetArray& rclFAry = _rclMesh.GetFacets(); + const MeshPointArray& rclPAry = _rclMesh.GetPoints(); std::size_t facetCount = rclFAry.size(); float fCosMaxAngle = static_cast(cos(fMaxAngle)); - std::priority_queue, - std::greater<> > todo; + std::priority_queue, std::greater<>> todo; for (std::size_t index = 0; index < facetCount; index++) { - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { const MeshFacet& facet = rclFAry[index]; const Base::Vector3f& p1 = rclPAry[facet._aulPoints[i]]; - const Base::Vector3f& p2 = rclPAry[facet._aulPoints[(i+1)%3]]; - const Base::Vector3f& p3 = rclPAry[facet._aulPoints[(i+2)%3]]; - Base::Vector3f dir1(p2-p1); dir1.Normalize(); - Base::Vector3f dir2(p3-p1); dir2.Normalize(); + const Base::Vector3f& p2 = rclPAry[facet._aulPoints[(i + 1) % 3]]; + const Base::Vector3f& p3 = rclPAry[facet._aulPoints[(i + 2) % 3]]; + Base::Vector3f dir1(p2 - p1); + dir1.Normalize(); + Base::Vector3f dir2(p3 - p1); + dir2.Normalize(); float fCosAngle = dir1.Dot(dir2); if (fCosAngle < fCosMaxAngle) { @@ -640,31 +677,36 @@ bool MeshFixCaps::Fixup() // the facet points may have changed, so check the current distance again const MeshFacet& facet = rclFAry[facevertex.first]; const Base::Vector3f& p1 = rclPAry[facet._aulPoints[facevertex.second]]; - const Base::Vector3f& p2 = rclPAry[facet._aulPoints[(facevertex.second+1)%3]]; - const Base::Vector3f& p3 = rclPAry[facet._aulPoints[(facevertex.second+2)%3]]; - Base::Vector3f dir1(p2-p1); dir1.Normalize(); - Base::Vector3f dir2(p3-p1); dir2.Normalize(); + const Base::Vector3f& p2 = rclPAry[facet._aulPoints[(facevertex.second + 1) % 3]]; + const Base::Vector3f& p3 = rclPAry[facet._aulPoints[(facevertex.second + 2) % 3]]; + Base::Vector3f dir1(p2 - p1); + dir1.Normalize(); + Base::Vector3f dir2(p3 - p1); + dir2.Normalize(); // check that the criterion is still OK in case // an earlier edge-swap has an impact float fCosAngle = dir1.Dot(dir2); - if (fCosAngle >= fCosMaxAngle) + if (fCosAngle >= fCosMaxAngle) { continue; + } // the triangle shouldn't be a needle, therefore the projection of the point with // the maximum angle must have a clear distance to the other corner points // as factor we choose a default value of 25% of the corresponding edge length - Base::Vector3f p4 = p1.Perpendicular(p2, p3-p2); - float distP2P3 = Base::Distance(p2,p3); - float distP2P4 = Base::Distance(p2,p4); - float distP3P4 = Base::Distance(p3,p4); - if (distP2P4/distP2P3 < fSplitFactor || distP3P4/distP2P3 < fSplitFactor) + Base::Vector3f p4 = p1.Perpendicular(p2, p3 - p2); + float distP2P3 = Base::Distance(p2, p3); + float distP2P4 = Base::Distance(p2, p4); + float distP3P4 = Base::Distance(p3, p4); + if (distP2P4 / distP2P3 < fSplitFactor || distP3P4 / distP2P3 < fSplitFactor) { continue; + } FacetIndex facetpos = facevertex.first; - FacetIndex neighbour = rclFAry[facetpos]._aulNeighbours[(facevertex.second+1)%3]; - if (neighbour != FACET_INDEX_MAX) + FacetIndex neighbour = rclFAry[facetpos]._aulNeighbours[(facevertex.second + 1) % 3]; + if (neighbour != FACET_INDEX_MAX) { topAlg.SwapEdge(facetpos, neighbour); + } } return true; @@ -679,8 +721,9 @@ bool MeshEvalDeformedFacets::Evaluate() MeshFacetIterator it(_rclMesh); for (it.Init(); it.More(); it.Next()) { - if (it->IsDeformed(fCosMinAngle, fCosMaxAngle)) + if (it->IsDeformed(fCosMinAngle, fCosMaxAngle)) { return false; + } } return true; @@ -694,8 +737,9 @@ std::vector MeshEvalDeformedFacets::GetIndices() const std::vector aInds; MeshFacetIterator it(_rclMesh); for (it.Init(); it.More(); it.Next()) { - if (it->IsDeformed(fCosMinAngle, fCosMaxAngle)) + if (it->IsDeformed(fCosMinAngle, fCosMaxAngle)) { aInds.push_back(it.Position()); + } } return aInds; @@ -706,7 +750,7 @@ bool MeshFixDeformedFacets::Fixup() float fCosMinAngle = cos(fMinAngle); float fCosMaxAngle = cos(fMaxAngle); - Base::Vector3f u,v; + Base::Vector3f u, v; MeshTopoAlgorithm cTopAlg(_rclMesh); MeshFacetIterator it(_rclMesh); @@ -714,12 +758,12 @@ bool MeshFixDeformedFacets::Fixup() // possibly deformed but not degenerated if (!it->IsDegenerated(fEpsilon)) { // store the angles to avoid to compute twice - float fCosAngles[3] = {0,0,0}; - bool done=false; + float fCosAngles[3] = {0, 0, 0}; + bool done = false; - for (int i=0; i<3; i++) { - u = it->_aclPoints[(i+1)%3]-it->_aclPoints[i]; - v = it->_aclPoints[(i+2)%3]-it->_aclPoints[i]; + for (int i = 0; i < 3; i++) { + u = it->_aclPoints[(i + 1) % 3] - it->_aclPoints[i]; + v = it->_aclPoints[(i + 2) % 3] - it->_aclPoints[i]; u.Normalize(); v.Normalize(); @@ -728,12 +772,13 @@ bool MeshFixDeformedFacets::Fixup() } // first check for angle > 120 deg: in this case we swap with the opposite edge - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { float fCosAngle = fCosAngles[i]; if (fCosAngle < fCosMaxAngle) { const MeshFacet& face = it.GetReference(); - FacetIndex uNeighbour = face._aulNeighbours[(i+1)%3]; - if (uNeighbour!=FACET_INDEX_MAX && cTopAlg.ShouldSwapEdge(it.Position(), uNeighbour, fMaxSwapAngle)) { + FacetIndex uNeighbour = face._aulNeighbours[(i + 1) % 3]; + if (uNeighbour != FACET_INDEX_MAX + && cTopAlg.ShouldSwapEdge(it.Position(), uNeighbour, fMaxSwapAngle)) { cTopAlg.SwapEdge(it.Position(), uNeighbour); done = true; } @@ -742,23 +787,27 @@ bool MeshFixDeformedFacets::Fixup() } // we have swapped already - if (done) + if (done) { continue; + } - // now check for angle < 30 deg: in this case we swap with one of the edges the corner is part of - for (int j=0; j<3; j++) { + // now check for angle < 30 deg: in this case we swap with one of the edges the corner + // is part of + for (int j = 0; j < 3; j++) { float fCosAngle = fCosAngles[j]; if (fCosAngle > fCosMinAngle) { const MeshFacet& face = it.GetReference(); FacetIndex uNeighbour = face._aulNeighbours[j]; - if (uNeighbour!=FACET_INDEX_MAX && cTopAlg.ShouldSwapEdge(it.Position(), uNeighbour, fMaxSwapAngle)) { + if (uNeighbour != FACET_INDEX_MAX + && cTopAlg.ShouldSwapEdge(it.Position(), uNeighbour, fMaxSwapAngle)) { cTopAlg.SwapEdge(it.Position(), uNeighbour); break; } - uNeighbour = face._aulNeighbours[(j+2)%3]; - if (uNeighbour!=FACET_INDEX_MAX && cTopAlg.ShouldSwapEdge(it.Position(), uNeighbour, fMaxSwapAngle)) { + uNeighbour = face._aulNeighbours[(j + 2) % 3]; + if (uNeighbour != FACET_INDEX_MAX + && cTopAlg.ShouldSwapEdge(it.Position(), uNeighbour, fMaxSwapAngle)) { cTopAlg.SwapEdge(it.Position(), uNeighbour); break; } @@ -779,10 +828,10 @@ bool MeshFixMergeFacets::Fixup() unsigned long countPoints = _rclMesh.CountPoints(); std::vector newFacets; - newFacets.reserve(countPoints/20); // 5% should be sufficient + newFacets.reserve(countPoints / 20); // 5% should be sufficient MeshTopoAlgorithm topAlg(_rclMesh); - for (unsigned long i=0; iindices.clear(); - MeshRefPointToFacets clPt2Facets(_rclMesh); + MeshRefPointToFacets clPt2Facets(_rclMesh); const MeshPointArray& rPntAry = _rclMesh.GetPoints(); MeshFacetArray::_TConstIterator f_beg = _rclMesh.GetFacets().begin(); MeshGeomFacet rTriangle; Base::Vector3f tmp; unsigned long ctPoints = _rclMesh.CountPoints(); - for (unsigned long index=0; index < ctPoints; index++) { + for (unsigned long index = 0; index < ctPoints; index++) { std::vector point; point.push_back(index); // get the local neighbourhood of the point - std::set nb = clPt2Facets.NeighbourPoints(point,1); + std::set nb = clPt2Facets.NeighbourPoints(point, 1); const std::set& faces = clPt2Facets[index]; for (PointIndex pt : nb) { const MeshPoint& mp = rPntAry[pt]; for (FacetIndex ft : faces) { - // the point must not be part of the facet we test - if (f_beg[ft]._aulPoints[0] == pt) - continue; - if (f_beg[ft]._aulPoints[1] == pt) - continue; - if (f_beg[ft]._aulPoints[2] == pt) - continue; - // is the point projectable onto the facet? - rTriangle = _rclMesh.GetFacet(f_beg[ft]); - if (rTriangle.IntersectWithLine(mp,rTriangle.GetNormal(),tmp)) { - const std::set& f = clPt2Facets[pt]; - this->indices.insert(this->indices.end(), f.begin(), f.end()); - break; - } + // the point must not be part of the facet we test + if (f_beg[ft]._aulPoints[0] == pt) { + continue; + } + if (f_beg[ft]._aulPoints[1] == pt) { + continue; + } + if (f_beg[ft]._aulPoints[2] == pt) { + continue; + } + // is the point projectable onto the facet? + rTriangle = _rclMesh.GetFacet(f_beg[ft]); + if (rTriangle.IntersectWithLine(mp, rTriangle.GetNormal(), tmp)) { + const std::set& f = clPt2Facets[pt]; + this->indices.insert(this->indices.end(), f.begin(), f.end()); + break; + } } } } // remove duplicates std::sort(this->indices.begin(), this->indices.end()); - this->indices.erase(std::unique(this->indices.begin(), - this->indices.end()), this->indices.end()); + this->indices.erase(std::unique(this->indices.begin(), this->indices.end()), + this->indices.end()); return this->indices.empty(); } @@ -859,9 +911,11 @@ Forbidden is: Repair: + store the point indices which can be projected on a face + store the face indices on which a point can be projected - + remove faces with an edge length smaller than a certain threshold (e.g. 0.01) from the stored triangles or that reference one of the stored points + + remove faces with an edge length smaller than a certain threshold (e.g. 0.01) from the stored +triangles or that reference one of the stored points + for this edge merge the two points - + if a point of a face can be projected onto another face and they have a common point then split the second face if the distance is under a certain threshold + + if a point of a face can be projected onto another face and they have a common point then split +the second face if the distance is under a certain threshold */ bool MeshFixDentsOnSurface::Fixup() { @@ -880,12 +934,12 @@ bool MeshEvalFoldsOnSurface::Evaluate() { this->indices.clear(); const MeshFacetArray& rFAry = _rclMesh.GetFacets(); - unsigned long ct=0; + unsigned long ct = 0; for (MeshFacetArray::const_iterator it = rFAry.begin(); it != rFAry.end(); ++it, ct++) { - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { FacetIndex n1 = it->_aulNeighbours[i]; - FacetIndex n2 = it->_aulNeighbours[(i+1)%3]; - Base::Vector3f v1 =_rclMesh.GetFacet(*it).GetNormal(); + FacetIndex n2 = it->_aulNeighbours[(i + 1) % 3]; + Base::Vector3f v1 = _rclMesh.GetFacet(*it).GetNormal(); if (n1 != FACET_INDEX_MAX && n2 != FACET_INDEX_MAX) { Base::Vector3f v2 = _rclMesh.GetFacet(n1).GetNormal(); Base::Vector3f v3 = _rclMesh.GetFacet(n2).GetNormal(); @@ -902,8 +956,8 @@ bool MeshEvalFoldsOnSurface::Evaluate() // remove duplicates std::sort(this->indices.begin(), this->indices.end()); - this->indices.erase(std::unique(this->indices.begin(), - this->indices.end()), this->indices.end()); + this->indices.erase(std::unique(this->indices.begin(), this->indices.end()), + this->indices.end()); return this->indices.empty(); } @@ -927,8 +981,9 @@ bool MeshEvalFoldsOnBoundary::Evaluate() MeshGeomFacet f1 = _rclMesh.GetFacet(*it); MeshGeomFacet f2 = _rclMesh.GetFacet(nbIndex); float cos_angle = f1.GetNormal() * f2.GetNormal(); - if (cos_angle <= 0.5f) // ~ 60 degree - indices.push_back(it-rFacAry.begin()); + if (cos_angle <= 0.5f) { // ~ 60 degree + indices.push_back(it - rFacAry.begin()); + } } } } @@ -959,23 +1014,22 @@ bool MeshEvalFoldOversOnSurface::Evaluate() { this->indices.clear(); const MeshCore::MeshFacetArray& facets = _rclMesh.GetFacets(); - MeshCore::MeshFacetArray::_TConstIterator f_it, - f_beg = facets.begin(), f_end = facets.end(); + MeshCore::MeshFacetArray::_TConstIterator f_it, f_beg = facets.begin(), f_end = facets.end(); Base::Vector3f n1, n2; for (f_it = facets.begin(); f_it != f_end; ++f_it) { - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { FacetIndex index1 = f_it->_aulNeighbours[i]; - FacetIndex index2 = f_it->_aulNeighbours[(i+1)%3]; + FacetIndex index2 = f_it->_aulNeighbours[(i + 1) % 3]; if (index1 != FACET_INDEX_MAX && index2 != FACET_INDEX_MAX) { // if the topology is correct but the normals flip from // two neighbours we have a fold - if (f_it->HasSameOrientation(f_beg[index1]) && - f_it->HasSameOrientation(f_beg[index2])) { + if (f_it->HasSameOrientation(f_beg[index1]) + && f_it->HasSameOrientation(f_beg[index2])) { n1 = _rclMesh.GetFacet(index1).GetNormal(); n2 = _rclMesh.GetFacet(index2).GetNormal(); - if (n1 * n2 < -0.5f) { // angle > 120 deg - this->indices.push_back(f_it-f_beg); + if (n1 * n2 < -0.5f) { // angle > 120 deg + this->indices.push_back(f_it - f_beg); break; } } @@ -991,8 +1045,7 @@ bool MeshEvalFoldOversOnSurface::Evaluate() bool MeshEvalBorderFacet::Evaluate() { const MeshCore::MeshFacetArray& facets = _rclMesh.GetFacets(); - MeshCore::MeshFacetArray::_TConstIterator f_it, - f_beg = facets.begin(), f_end = facets.end(); + MeshCore::MeshFacetArray::_TConstIterator f_it, f_beg = facets.begin(), f_end = facets.end(); MeshCore::MeshRefPointToPoints vv_it(_rclMesh); MeshCore::MeshRefPointToFacets vf_it(_rclMesh); @@ -1005,8 +1058,9 @@ bool MeshEvalBorderFacet::Evaluate() } } - if (ok) - _facets.push_back(f_it-f_beg); + if (ok) { + _facets.push_back(f_it - f_beg); + } } return _facets.empty(); @@ -1019,7 +1073,7 @@ bool MeshEvalRangeFacet::Evaluate() const MeshFacetArray& rFaces = _rclMesh.GetFacets(); FacetIndex ulCtFacets = rFaces.size(); - for (const auto & it : rFaces) { + for (const auto& it : rFaces) { for (FacetIndex nbFacet : it._aulNeighbours) { if ((nbFacet >= ulCtFacets) && (nbFacet < FACET_INDEX_MAX)) { return false; @@ -1036,7 +1090,7 @@ std::vector MeshEvalRangeFacet::GetIndices() const const MeshFacetArray& rFaces = _rclMesh.GetFacets(); FacetIndex ulCtFacets = rFaces.size(); - FacetIndex ind=0; + FacetIndex ind = 0; for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, ind++) { for (FacetIndex nbIndex : it->_aulNeighbours) { if ((nbIndex >= ulCtFacets) && (nbIndex < FACET_INDEX_MAX)) { @@ -1062,11 +1116,15 @@ bool MeshEvalRangePoint::Evaluate() const MeshFacetArray& rFaces = _rclMesh.GetFacets(); PointIndex ulCtPoints = _rclMesh.CountPoints(); - for (const auto & it : rFaces) { - if (std::find_if(it._aulPoints, it._aulPoints + 3, [ulCtPoints](PointIndex i) { - return i >= ulCtPoints; - }) < it._aulPoints + 3) + for (const auto& it : rFaces) { + if (std::find_if(it._aulPoints, + it._aulPoints + 3, + [ulCtPoints](PointIndex i) { + return i >= ulCtPoints; + }) + < it._aulPoints + 3) { return false; + } } return true; @@ -1078,12 +1136,16 @@ std::vector MeshEvalRangePoint::GetIndices() const const MeshFacetArray& rFaces = _rclMesh.GetFacets(); PointIndex ulCtPoints = _rclMesh.CountPoints(); - PointIndex ind=0; + PointIndex ind = 0; for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, ind++) { - if (std::find_if(it->_aulPoints, it->_aulPoints + 3, [ulCtPoints](PointIndex i) { - return i >= ulCtPoints; - }) < it->_aulPoints + 3) + if (std::find_if(it->_aulPoints, + it->_aulPoints + 3, + [ulCtPoints](PointIndex i) { + return i >= ulCtPoints; + }) + < it->_aulPoints + 3) { aInds.push_back(ind); + } } return aInds; @@ -1115,56 +1177,55 @@ bool MeshFixRangePoint::Fixup() bool MeshEvalCorruptedFacets::Evaluate() { - const MeshFacetArray& rFaces = _rclMesh.GetFacets(); + const MeshFacetArray& rFaces = _rclMesh.GetFacets(); - for (const auto & it : rFaces) { - // duplicated point indices - if (it.IsDegenerated()) - return false; - } + for (const auto& it : rFaces) { + // duplicated point indices + if (it.IsDegenerated()) { + return false; + } + } - return true; + return true; } std::vector MeshEvalCorruptedFacets::GetIndices() const { - std::vector aInds; - const MeshFacetArray& rFaces = _rclMesh.GetFacets(); - FacetIndex ind=0; + std::vector aInds; + const MeshFacetArray& rFaces = _rclMesh.GetFacets(); + FacetIndex ind = 0; - for ( MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, ind++ ) { - if (it->IsDegenerated()) - aInds.push_back(ind); - } + for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, ind++) { + if (it->IsDegenerated()) { + aInds.push_back(ind); + } + } - return aInds; + return aInds; } bool MeshFixCorruptedFacets::Fixup() { - MeshTopoAlgorithm cTopAlg(_rclMesh); - - MeshFacetIterator it(_rclMesh); - for ( it.Init(); it.More(); it.Next() ) - { - if ( it.GetReference().IsDegenerated() ) - { - unsigned long uId = it.Position(); - bool removed = cTopAlg.RemoveCorruptedFacet(uId); - if (removed) { - // due to a modification of the array the iterator became invalid - it.Set(uId-1); - } + MeshTopoAlgorithm cTopAlg(_rclMesh); + MeshFacetIterator it(_rclMesh); + for (it.Init(); it.More(); it.Next()) { + if (it.GetReference().IsDegenerated()) { + unsigned long uId = it.Position(); + bool removed = cTopAlg.RemoveCorruptedFacet(uId); + if (removed) { + // due to a modification of the array the iterator became invalid + it.Set(uId - 1); + } + } } - } - return true; + return true; } // ---------------------------------------------------------------------- -bool MeshEvalPointOnEdge::Evaluate () +bool MeshEvalPointOnEdge::Evaluate() { MeshFacetGrid facetGrid(_rclMesh); const MeshPointArray& points = _rclMesh.GetPoints(); @@ -1176,11 +1237,12 @@ bool MeshEvalPointOnEdge::Evaluate () for (int i = 0; i < 3; i++) { MeshGeomEdge edge; edge._aclPoints[0] = points[facet._aulPoints[i]]; - edge._aclPoints[1] = points[facet._aulPoints[(i+1)%3]]; + edge._aclPoints[1] = points[facet._aulPoints[(i + 1) % 3]]; if (edge.GetBoundBox().IsInBox(points[idx])) { - if (edge.IsPointOf(points[idx], 0.001f)) + if (edge.IsPointOf(points[idx], 0.001f)) { return true; + } } } } @@ -1188,7 +1250,7 @@ bool MeshEvalPointOnEdge::Evaluate () }; PointIndex maxPoints = _rclMesh.CountPoints(); - for (PointIndex i = 0; i < maxPoints; i++) { + for (PointIndex i = 0; i < maxPoints; i++) { std::vector elements; facetGrid.GetElements(points[i], elements); @@ -1196,8 +1258,9 @@ bool MeshEvalPointOnEdge::Evaluate () const MeshFacet& face = facets[it]; if (IsPointOnEdge(i, face)) { pointsIndices.push_back(i); - if (face.HasOpenEdge()) + if (face.HasOpenEdge()) { facetsIndices.push_back(it); + } } } } @@ -1214,7 +1277,7 @@ std::vector MeshEvalPointOnEdge::GetFacetIndices() const return facetsIndices; } -bool MeshFixPointOnEdge::Fixup () +bool MeshFixPointOnEdge::Fixup() { MeshEvalPointOnEdge eval(_rclMesh); eval.Evaluate(); @@ -1229,10 +1292,11 @@ bool MeshFixPointOnEdge::Fixup () _rclMesh.DeletePoints(pointsIndices); if (fillBoundary) { - std::list > borderList; + std::list> borderList; FindBoundaries(borderList); - if (!borderList.empty()) + if (!borderList.empty()) { FillBoundaries(borderList); + } } } @@ -1246,7 +1310,7 @@ void MeshFixPointOnEdge::MarkBoundaries(const std::vector& facetsInd meshalg.SetFacetsFlag(facetsIndices, MeshFacet::TMP0); } -void MeshFixPointOnEdge::FindBoundaries(std::list >& borderList) +void MeshFixPointOnEdge::FindBoundaries(std::list>& borderList) { std::vector tmp; MeshAlgorithm meshalg(_rclMesh); @@ -1257,11 +1321,11 @@ void MeshFixPointOnEdge::FindBoundaries(std::list >& bor } } -void MeshFixPointOnEdge::FillBoundaries(const std::list >& borderList) +void MeshFixPointOnEdge::FillBoundaries(const std::list>& borderList) { FlatTriangulator tria; tria.SetVerifier(new MeshCore::TriangulationVerifierV2); MeshTopoAlgorithm topalg(_rclMesh); - std::list > failed; + std::list> failed; topalg.FillupHoles(1, tria, borderList, failed); } diff --git a/src/Mod/Mesh/App/Core/Degeneration.h b/src/Mod/Mesh/App/Core/Degeneration.h index 480a767269..0baf629930 100644 --- a/src/Mod/Mesh/App/Core/Degeneration.h +++ b/src/Mod/Mesh/App/Core/Degeneration.h @@ -30,7 +30,8 @@ #include "Evaluation.h" -namespace MeshCore { +namespace MeshCore +{ class MeshKernel; class MeshGeomFacet; @@ -43,21 +44,23 @@ class MeshFacetIterator; * @see MeshFixInvalids * @author Werner Mayer */ -class MeshExport MeshEvalInvalids : public MeshEvaluation +class MeshExport MeshEvalInvalids: public MeshEvaluation { public: - /** - * Construction. - */ - explicit MeshEvalInvalids (const MeshKernel &rclM) : MeshEvaluation( rclM ) { } - /** - * Searches for as 'Invalid' marked points or facets. - */ - bool Evaluate () override; - /** - * Returns the indices of all invalid facets or facets whose points are invalid. - */ - std::vector GetIndices() const; + /** + * Construction. + */ + explicit MeshEvalInvalids(const MeshKernel& rclM) + : MeshEvaluation(rclM) + {} + /** + * Searches for as 'Invalid' marked points or facets. + */ + bool Evaluate() override; + /** + * Returns the indices of all invalid facets or facets whose points are invalid. + */ + std::vector GetIndices() const; }; /** @@ -65,42 +68,48 @@ public: * @see MeshEvalInvalids * @author Werner Mayer */ -class MeshExport MeshFixInvalids : public MeshValidation +class MeshExport MeshFixInvalids: public MeshValidation { public: - /** - * Construction. - */ - explicit MeshFixInvalids (MeshKernel &rclM) : MeshValidation( rclM ) { } - /** - * Remove invalid elements. - */ - bool Fixup () override; + /** + * Construction. + */ + explicit MeshFixInvalids(MeshKernel& rclM) + : MeshValidation(rclM) + {} + /** + * Remove invalid elements. + */ + bool Fixup() override; }; /** * The MeshEvalDuplicatePoints class searches for duplicated points. - * A point is regarded as duplicated if the distances between x, y and z coordinates of two points is - * less than an epsilon (defined by MeshDefinitions::_fMinPointDistanceD1, default value=1.0e-5f). + * A point is regarded as duplicated if the distances between x, y and z coordinates of two points + * is less than an epsilon (defined by MeshDefinitions::_fMinPointDistanceD1, default + * value=1.0e-5f). * @see MeshFixDuplicatePoints * @see MeshEvalDegeneratedFacets * @author Werner Mayer */ -class MeshExport MeshEvalDuplicatePoints : public MeshEvaluation +class MeshExport MeshEvalDuplicatePoints: public MeshEvaluation { public: - /** - * Construction. - */ - explicit MeshEvalDuplicatePoints (const MeshKernel &rclM) : MeshEvaluation( rclM ) { } - /** - * Merges points to one if the distance between them is less than the global \a MeshDefinitions::_fMinPointDistanceD1. - */ - bool Evaluate () override; - /** - * Returns the indices of all duplicated points. - */ - std::vector GetIndices() const; + /** + * Construction. + */ + explicit MeshEvalDuplicatePoints(const MeshKernel& rclM) + : MeshEvaluation(rclM) + {} + /** + * Merges points to one if the distance between them is less than the global \a + * MeshDefinitions::_fMinPointDistanceD1. + */ + bool Evaluate() override; + /** + * Returns the indices of all duplicated points. + */ + std::vector GetIndices() const; }; /** @@ -108,17 +117,19 @@ public: * @see MeshEvalDuplicatePoints * @author Werner Mayer */ -class MeshExport MeshFixDuplicatePoints : public MeshValidation +class MeshExport MeshFixDuplicatePoints: public MeshValidation { public: - /** - * Construction. - */ - explicit MeshFixDuplicatePoints (MeshKernel &rclM) : MeshValidation( rclM ) { } - /** - * Merges duplicated points. - */ - bool Fixup () override; + /** + * Construction. + */ + explicit MeshFixDuplicatePoints(MeshKernel& rclM) + : MeshValidation(rclM) + {} + /** + * Merges duplicated points. + */ + bool Fixup() override; }; /** @@ -126,21 +137,23 @@ public: * @see MeshFixNaNPoints * @author Werner Mayer */ -class MeshExport MeshEvalNaNPoints : public MeshEvaluation +class MeshExport MeshEvalNaNPoints: public MeshEvaluation { public: - /** - * Construction. - */ - explicit MeshEvalNaNPoints (const MeshKernel &rclM) : MeshEvaluation( rclM ) { } - /** - * Returns false if a point with NaN coordinate is found. - */ - bool Evaluate () override; - /** - * Returns the indices of all NaN points. - */ - std::vector GetIndices() const; + /** + * Construction. + */ + explicit MeshEvalNaNPoints(const MeshKernel& rclM) + : MeshEvaluation(rclM) + {} + /** + * Returns false if a point with NaN coordinate is found. + */ + bool Evaluate() override; + /** + * Returns the indices of all NaN points. + */ + std::vector GetIndices() const; }; /** @@ -148,41 +161,45 @@ public: * @see MeshEvalNaNPoints * @author Werner Mayer */ -class MeshExport MeshFixNaNPoints : public MeshValidation +class MeshExport MeshFixNaNPoints: public MeshValidation { public: - /** - * Construction. - */ - explicit MeshFixNaNPoints (MeshKernel &rclM) : MeshValidation( rclM ) { } - /** - * Merges duplicated points. - */ - bool Fixup () override; + /** + * Construction. + */ + explicit MeshFixNaNPoints(MeshKernel& rclM) + : MeshValidation(rclM) + {} + /** + * Merges duplicated points. + */ + bool Fixup() override; }; /** * The MeshEvalDuplicateFacets class searches for duplicated facets. - * A facet is regarded as duplicated if all its point indices refer to the same location in the point array of the mesh kernel. - * The actual geometric points are not taken into consideration. + * A facet is regarded as duplicated if all its point indices refer to the same location in the + * point array of the mesh kernel. The actual geometric points are not taken into consideration. * @see MeshFixDuplicateFacets * @author Werner Mayer */ -class MeshExport MeshEvalDuplicateFacets : public MeshEvaluation +class MeshExport MeshEvalDuplicateFacets: public MeshEvaluation { public: - /** - * Construction. - */ - explicit MeshEvalDuplicateFacets (const MeshKernel &rclM) : MeshEvaluation( rclM ) { } - /** - * Searches for duplicated facets. - */ - bool Evaluate () override; - /** - * Returns the indices of all duplicated facets. - */ - std::vector GetIndices() const; + /** + * Construction. + */ + explicit MeshEvalDuplicateFacets(const MeshKernel& rclM) + : MeshEvaluation(rclM) + {} + /** + * Searches for duplicated facets. + */ + bool Evaluate() override; + /** + * Returns the indices of all duplicated facets. + */ + std::vector GetIndices() const; }; /** @@ -190,76 +207,85 @@ public: * @see MeshEvalDuplicateFacets * @author Werner Mayer */ -class MeshExport MeshFixDuplicateFacets : public MeshValidation +class MeshExport MeshFixDuplicateFacets: public MeshValidation { public: - /** - * Construction. - */ - explicit MeshFixDuplicateFacets (MeshKernel &rclM) : MeshValidation( rclM ) { } - /** - * Removes duplicated facets. - */ - bool Fixup () override; + /** + * Construction. + */ + explicit MeshFixDuplicateFacets(MeshKernel& rclM) + : MeshValidation(rclM) + {} + /** + * Removes duplicated facets. + */ + bool Fixup() override; }; /** * The MeshEvalInternalFacets class identifies internal facets of a volume mesh. * @author Werner Mayer */ -class MeshExport MeshEvalInternalFacets : public MeshEvaluation +class MeshExport MeshEvalInternalFacets: public MeshEvaluation { public: - /** - * Construction. - */ - explicit MeshEvalInternalFacets (const MeshKernel &rclM) : MeshEvaluation( rclM ) { } - /** - * Identify internal facets. - */ - bool Evaluate () override; - /** - * Return the indices. - */ - const std::vector& GetIndices() const - { return _indices; } + /** + * Construction. + */ + explicit MeshEvalInternalFacets(const MeshKernel& rclM) + : MeshEvaluation(rclM) + {} + /** + * Identify internal facets. + */ + bool Evaluate() override; + /** + * Return the indices. + */ + const std::vector& GetIndices() const + { + return _indices; + } private: std::vector _indices; }; /** - * The MeshEvalDegeneratedFacets class searches for degenerated facets. A facet is degenerated either if its points - * are collinear, i.e. they lie on a line or two points are coincident. In the latter case these points are duplicated. - * If a facet refers to at least two equal point indices then the facet is also regarded is 'corrupt'. + * The MeshEvalDegeneratedFacets class searches for degenerated facets. A facet is degenerated + * either if its points are collinear, i.e. they lie on a line or two points are coincident. In the + * latter case these points are duplicated. If a facet refers to at least two equal point indices + * then the facet is also regarded is 'corrupt'. * @see MeshEvalCorruptedFacets * @see MeshEvalDuplicatePoints * @see MeshFixDegeneratedFacets * @author Werner Mayer */ -class MeshExport MeshEvalDegeneratedFacets : public MeshEvaluation +class MeshExport MeshEvalDegeneratedFacets: public MeshEvaluation { public: - /** - * Construction. - */ - MeshEvalDegeneratedFacets (const MeshKernel &rclM, float fEps) - : MeshEvaluation(rclM), fEpsilon(fEps) {} - /** - * Searches degenerated facets. - */ - bool Evaluate () override; - /** - * Returns the number of facets with an edge smaller than \a fMinEdgeLength. - */ - unsigned long CountEdgeTooSmall (float fMinEdgeLength) const; - /** - * Returns the indices of all corrupt facets. - */ - std::vector GetIndices() const; + /** + * Construction. + */ + MeshEvalDegeneratedFacets(const MeshKernel& rclM, float fEps) + : MeshEvaluation(rclM) + , fEpsilon(fEps) + {} + /** + * Searches degenerated facets. + */ + bool Evaluate() override; + /** + * Returns the number of facets with an edge smaller than \a fMinEdgeLength. + */ + unsigned long CountEdgeTooSmall(float fMinEdgeLength) const; + /** + * Returns the indices of all corrupt facets. + */ + std::vector GetIndices() const; private: - float fEpsilon; + float fEpsilon; }; /** @@ -267,21 +293,23 @@ private: * @see MeshEvalDegeneratedFacets * @author Werner Mayer */ -class MeshExport MeshFixDegeneratedFacets : public MeshValidation +class MeshExport MeshFixDegeneratedFacets: public MeshValidation { public: - /** - * Construction. - */ - MeshFixDegeneratedFacets (MeshKernel &rclM, float fEps) - : MeshValidation(rclM), fEpsilon(fEps) { } - /** - * Removes degenerated facets. - */ - bool Fixup () override; + /** + * Construction. + */ + MeshFixDegeneratedFacets(MeshKernel& rclM, float fEps) + : MeshValidation(rclM) + , fEpsilon(fEps) + {} + /** + * Removes degenerated facets. + */ + bool Fixup() override; private: - float fEpsilon; + float fEpsilon; }; /** @@ -292,7 +320,7 @@ private: * @see MeshFixCaps * @author Werner Mayer */ -class MeshExport MeshRemoveNeedles : public MeshValidation +class MeshExport MeshRemoveNeedles: public MeshValidation { public: /** @@ -300,16 +328,18 @@ public: * It defines the amount of perimeter of a triangle for which the shortest * edge is considered for removal. */ - explicit MeshRemoveNeedles (MeshKernel &rclM, float fMinEdgeLen = 0.05f) - : MeshValidation(rclM), fMinEdgeLength(std::min(fMinEdgeLen, 0.25f)) {} - /** - * Removes all facets with an edge smaller than \a fMinEdgeLength without leaving holes or gaps - * in the mesh. - */ - bool Fixup () override; + explicit MeshRemoveNeedles(MeshKernel& rclM, float fMinEdgeLen = 0.05f) + : MeshValidation(rclM) + , fMinEdgeLength(std::min(fMinEdgeLen, 0.25f)) + {} + /** + * Removes all facets with an edge smaller than \a fMinEdgeLength without leaving holes or gaps + * in the mesh. + */ + bool Fixup() override; private: - float fMinEdgeLength; + float fMinEdgeLength; }; /** @@ -322,21 +352,26 @@ private: * @see MeshRemoveNeedles * @author Werner Mayer */ -class MeshExport MeshFixCaps : public MeshValidation +class MeshExport MeshFixCaps: public MeshValidation { public: - /** - * Construction. The \arg fFactor must be in the range of 0.0 and 0.5. - */ - explicit MeshFixCaps (MeshKernel &rclM, float fMaxAng = 2.61f, float fFactor = 0.25f) // ~150 degree - : MeshValidation(rclM), fMaxAngle(fMaxAng), fSplitFactor(fFactor) { } - /** - */ - bool Fixup () override; + /** + * Construction. The \arg fFactor must be in the range of 0.0 and 0.5. + */ + explicit MeshFixCaps(MeshKernel& rclM, + float fMaxAng = 2.61f, + float fFactor = 0.25f) // ~150 degree + : MeshValidation(rclM) + , fMaxAngle(fMaxAng) + , fSplitFactor(fFactor) + {} + /** + */ + bool Fixup() override; private: - float fMaxAngle; - float fSplitFactor; + float fMaxAngle; + float fSplitFactor; }; /** @@ -345,86 +380,108 @@ private: * @see MeshFixDegeneratedFacets * @author Werner Mayer */ -class MeshExport MeshEvalDeformedFacets : public MeshEvaluation +class MeshExport MeshEvalDeformedFacets: public MeshEvaluation { public: - /** - * Construction. - */ - MeshEvalDeformedFacets (const MeshKernel &rclM, float fMinAngle, float fMaxAngle) - : MeshEvaluation(rclM), fMinAngle(fMinAngle), fMaxAngle(fMaxAngle) { } - /** - * Searches deformed facets. - */ - bool Evaluate () override; - /** - * Returns the indices of deformed facets. - */ - std::vector GetIndices() const; + /** + * Construction. + */ + MeshEvalDeformedFacets(const MeshKernel& rclM, float fMinAngle, float fMaxAngle) + : MeshEvaluation(rclM) + , fMinAngle(fMinAngle) + , fMaxAngle(fMaxAngle) + {} + /** + * Searches deformed facets. + */ + bool Evaluate() override; + /** + * Returns the indices of deformed facets. + */ + std::vector GetIndices() const; private: - float fMinAngle; /**< If an angle of a facet is lower than fMinAngle it's considered as deformed. */ - float fMaxAngle; /**< If an angle of a facet is higher than fMaxAngle it's considered as deformed. */ + float fMinAngle; /**< If an angle of a facet is lower than fMinAngle it's considered as + deformed. */ + float fMaxAngle; /**< If an angle of a facet is higher than fMaxAngle it's considered as + deformed. */ }; /** - * The MeshFixDeformedFacets class tries to fix deformed facets by swapping the common edge with one of their neighbours. - * @note Degenerated facets are also deformed facet but this algorithm tries to fix deformed facets that or not degenerated. - * The removal of degenerated facets is done by @ref MeshFixDegeneratedFacets. + * The MeshFixDeformedFacets class tries to fix deformed facets by swapping the common edge with one + * of their neighbours. + * @note Degenerated facets are also deformed facet but this algorithm tries to fix deformed facets + * that or not degenerated. The removal of degenerated facets is done by @ref + * MeshFixDegeneratedFacets. * @see MeshEvalDeformedFacets * @author Werner Mayer */ -class MeshExport MeshFixDeformedFacets : public MeshValidation +class MeshExport MeshFixDeformedFacets: public MeshValidation { public: - /** - * Construction. - */ - MeshFixDeformedFacets (MeshKernel &rclM, float fMinAngle, float fMaxAngle, float fSwapAngle, float fEps) - : MeshValidation(rclM), fMinAngle(fMinAngle), fMaxAngle(fMaxAngle), - fMaxSwapAngle(fSwapAngle), fEpsilon(fEps) { } - /** - * Removes deformed facets. - */ - bool Fixup () override; + /** + * Construction. + */ + MeshFixDeformedFacets(MeshKernel& rclM, + float fMinAngle, + float fMaxAngle, + float fSwapAngle, + float fEps) + : MeshValidation(rclM) + , fMinAngle(fMinAngle) + , fMaxAngle(fMaxAngle) + , fMaxSwapAngle(fSwapAngle) + , fEpsilon(fEps) + {} + /** + * Removes deformed facets. + */ + bool Fixup() override; private: - float fMinAngle; /**< If an angle of a facet is lower than fMinAngle it's considered as deformed. */ - float fMaxAngle; /**< If an angle of a facet is higher than fMaxAngle it's considered as deformed. */ - float fMaxSwapAngle; /**< A swap edge is only allowed if the angle of both normals doesn't exceed fMaxSwapAngle */ - float fEpsilon; + float fMinAngle; /**< If an angle of a facet is lower than fMinAngle it's considered as + deformed. */ + float fMaxAngle; /**< If an angle of a facet is higher than fMaxAngle it's considered as + deformed. */ + float fMaxSwapAngle; /**< A swap edge is only allowed if the angle of both normals doesn't + exceed fMaxSwapAngle */ + float fEpsilon; }; /** - * The MeshFixMergeFacets class removes vertexes which have three adjacent vertexes and is referenced by three facets. - * Usually all the three facets that reference this vertex are not well-formed. If the number of adjacent vertexes - * is equal to the number of adjacent facets the affected vertex never lies on the boundary and thus it's safe to delete - * and replace the three facets with a single facet. - * Effectively this algorithm does the opposite of \ref MeshTopoAlgorithm::InsertVertex + * The MeshFixMergeFacets class removes vertexes which have three adjacent vertexes and is + * referenced by three facets. Usually all the three facets that reference this vertex are not + * well-formed. If the number of adjacent vertexes is equal to the number of adjacent facets the + * affected vertex never lies on the boundary and thus it's safe to delete and replace the three + * facets with a single facet. Effectively this algorithm does the opposite of \ref + * MeshTopoAlgorithm::InsertVertex * @author Werner Mayer */ -class MeshExport MeshFixMergeFacets : public MeshValidation +class MeshExport MeshFixMergeFacets: public MeshValidation { public: - /** - * Construction. - */ - explicit MeshFixMergeFacets (MeshKernel &rclM) - : MeshValidation(rclM) { } - /** - * Removes deformed facets. - */ - bool Fixup () override; + /** + * Construction. + */ + explicit MeshFixMergeFacets(MeshKernel& rclM) + : MeshValidation(rclM) + {} + /** + * Removes deformed facets. + */ + bool Fixup() override; }; /** * If an adjacent point (A) of a point (P) can be projected onto a triangle shared * by (P) but not by (A) then we have a local dent. The topology is not affected. */ -class MeshExport MeshEvalDentsOnSurface : public MeshEvaluation +class MeshExport MeshEvalDentsOnSurface: public MeshEvaluation { public: - explicit MeshEvalDentsOnSurface (const MeshKernel &rclM) : MeshEvaluation( rclM ) { } + explicit MeshEvalDentsOnSurface(const MeshKernel& rclM) + : MeshEvaluation(rclM) + {} bool Evaluate() override; std::vector GetIndices() const; @@ -433,10 +490,12 @@ private: std::vector indices; }; -class MeshExport MeshFixDentsOnSurface : public MeshValidation +class MeshExport MeshFixDentsOnSurface: public MeshValidation { public: - explicit MeshFixDentsOnSurface (MeshKernel &rclM) : MeshValidation( rclM ) { } + explicit MeshFixDentsOnSurface(MeshKernel& rclM) + : MeshValidation(rclM) + {} bool Fixup() override; }; @@ -446,10 +505,12 @@ public: * but the angles between both of these adjacent triangles is higher than 90 deg * we have a fold. The topology is not affected but the geometry is broken. */ -class MeshExport MeshEvalFoldsOnSurface : public MeshEvaluation +class MeshExport MeshEvalFoldsOnSurface: public MeshEvaluation { public: - explicit MeshEvalFoldsOnSurface (const MeshKernel &rclM) : MeshEvaluation( rclM ) { } + explicit MeshEvalFoldsOnSurface(const MeshKernel& rclM) + : MeshEvaluation(rclM) + {} bool Evaluate() override; std::vector GetIndices() const; @@ -464,10 +525,12 @@ private: * The topology is not affected there but such triangles can lead to problems * on some hole-filling algorithms. */ -class MeshExport MeshEvalFoldsOnBoundary : public MeshEvaluation +class MeshExport MeshEvalFoldsOnBoundary: public MeshEvaluation { public: - explicit MeshEvalFoldsOnBoundary (const MeshKernel &rclM) : MeshEvaluation( rclM ) { } + explicit MeshEvalFoldsOnBoundary(const MeshKernel& rclM) + : MeshEvaluation(rclM) + {} bool Evaluate() override; std::vector GetIndices() const; @@ -476,10 +539,12 @@ private: std::vector indices; }; -class MeshExport MeshFixFoldsOnBoundary : public MeshValidation +class MeshExport MeshFixFoldsOnBoundary: public MeshValidation { public: - explicit MeshFixFoldsOnBoundary (MeshKernel &rclM) : MeshValidation( rclM ) { } + explicit MeshFixFoldsOnBoundary(MeshKernel& rclM) + : MeshValidation(rclM) + {} bool Fixup() override; }; @@ -488,14 +553,18 @@ public: * Considers two adjacent triangles with an angle higher than 120 deg of their * normals as a fold-over. The topology is not affected there. */ -class MeshExport MeshEvalFoldOversOnSurface : public MeshEvaluation +class MeshExport MeshEvalFoldOversOnSurface: public MeshEvaluation { public: - explicit MeshEvalFoldOversOnSurface (const MeshKernel &rclM) : MeshEvaluation( rclM ) { } + explicit MeshEvalFoldOversOnSurface(const MeshKernel& rclM) + : MeshEvaluation(rclM) + {} bool Evaluate() override; std::vector GetIndices() const - { return this->indices; } + { + return this->indices; + } private: std::vector indices; @@ -506,12 +575,14 @@ private: * part of a boundary. * @see MeshEvalSingleFacet */ -class MeshExport MeshEvalBorderFacet : public MeshEvaluation +class MeshExport MeshEvalBorderFacet: public MeshEvaluation { public: - MeshEvalBorderFacet (const MeshKernel &rclB, std::vector& f) - : MeshEvaluation(rclB), _facets(f) {} - bool Evaluate() override; + MeshEvalBorderFacet(const MeshKernel& rclB, std::vector& f) + : MeshEvaluation(rclB) + , _facets(f) + {} + bool Evaluate() override; protected: std::vector& _facets; @@ -528,21 +599,23 @@ protected: * @see MeshFixRangeFacet * @author Werner Mayer */ -class MeshExport MeshEvalRangeFacet : public MeshEvaluation +class MeshExport MeshEvalRangeFacet: public MeshEvaluation { public: - /** - * Construction. - */ - explicit MeshEvalRangeFacet (const MeshKernel &rclM) : MeshEvaluation( rclM ) { } - /** - * Searches for facets that has neighbour facet indices out of range. - */ - bool Evaluate () override; - /** - * Returns the indices of all facets with invalid neighbour indices. - */ - std::vector GetIndices() const; + /** + * Construction. + */ + explicit MeshEvalRangeFacet(const MeshKernel& rclM) + : MeshEvaluation(rclM) + {} + /** + * Searches for facets that has neighbour facet indices out of range. + */ + bool Evaluate() override; + /** + * Returns the indices of all facets with invalid neighbour indices. + */ + std::vector GetIndices() const; }; /** @@ -550,17 +623,19 @@ public: * @see MeshEvalRangeFacet * @author Werner Mayer */ -class MeshExport MeshFixRangeFacet : public MeshValidation +class MeshExport MeshFixRangeFacet: public MeshValidation { public: - /** - * Construction. - */ - explicit MeshFixRangeFacet (MeshKernel &rclM) : MeshValidation( rclM ) { } - /** - * Fixes facets with neighbour indices out of range. - */ - bool Fixup () override; + /** + * Construction. + */ + explicit MeshFixRangeFacet(MeshKernel& rclM) + : MeshValidation(rclM) + {} + /** + * Fixes facets with neighbour indices out of range. + */ + bool Fixup() override; }; /** @@ -568,21 +643,23 @@ public: * @see MeshFixRangePoint * @author Werner Mayer */ -class MeshExport MeshEvalRangePoint : public MeshEvaluation +class MeshExport MeshEvalRangePoint: public MeshEvaluation { public: - /** - * Construction. - */ - explicit MeshEvalRangePoint (const MeshKernel &rclM) : MeshEvaluation( rclM ) { } - /** - * Searches for facets that has point indices out of range. - */ - bool Evaluate () override; - /** - * Returns the indices of all facets with invalid point indices. - */ - std::vector GetIndices() const; + /** + * Construction. + */ + explicit MeshEvalRangePoint(const MeshKernel& rclM) + : MeshEvaluation(rclM) + {} + /** + * Searches for facets that has point indices out of range. + */ + bool Evaluate() override; + /** + * Returns the indices of all facets with invalid point indices. + */ + std::vector GetIndices() const; }; /** @@ -590,17 +667,19 @@ public: * @see MeshFixRangePoint * @author Werner Mayer */ -class MeshExport MeshFixRangePoint : public MeshValidation +class MeshExport MeshFixRangePoint: public MeshValidation { public: - /** - * Construction. - */ - explicit MeshFixRangePoint (MeshKernel &rclM) : MeshValidation( rclM ) { } - /** - * Fixes facets with point indices out of range. - */ - bool Fixup () override; + /** + * Construction. + */ + explicit MeshFixRangePoint(MeshKernel& rclM) + : MeshValidation(rclM) + {} + /** + * Fixes facets with point indices out of range. + */ + bool Fixup() override; }; /** @@ -609,21 +688,23 @@ public: * @see MeshFixCorruptedFacets * @author Werner Mayer */ -class MeshExport MeshEvalCorruptedFacets : public MeshEvaluation +class MeshExport MeshEvalCorruptedFacets: public MeshEvaluation { public: - /** - * Construction. - */ - explicit MeshEvalCorruptedFacets (const MeshKernel &rclM) : MeshEvaluation( rclM ) { } - /** - * Searches for corrupted facets. - */ - bool Evaluate () override; - /** - * Returns the indices of all corrupt facets. - */ - std::vector GetIndices() const; + /** + * Construction. + */ + explicit MeshEvalCorruptedFacets(const MeshKernel& rclM) + : MeshEvaluation(rclM) + {} + /** + * Searches for corrupted facets. + */ + bool Evaluate() override; + /** + * Returns the indices of all corrupt facets. + */ + std::vector GetIndices() const; }; /** @@ -632,17 +713,19 @@ public: * @see MeshEvalCorruptedFacets * @author Werner Mayer */ -class MeshExport MeshFixCorruptedFacets : public MeshValidation +class MeshExport MeshFixCorruptedFacets: public MeshValidation { public: - /** - * Construction. - */ - explicit MeshFixCorruptedFacets (MeshKernel &rclM) : MeshValidation( rclM ) { } - /** - * Removes corrupted facets. - */ - bool Fixup () override; + /** + * Construction. + */ + explicit MeshFixCorruptedFacets(MeshKernel& rclM) + : MeshValidation(rclM) + {} + /** + * Removes corrupted facets. + */ + bool Fixup() override; }; /** @@ -650,29 +733,31 @@ public: * @see MeshFixPointOnEdge * @author Werner Mayer */ -class MeshExport MeshEvalPointOnEdge : public MeshEvaluation +class MeshExport MeshEvalPointOnEdge: public MeshEvaluation { public: - /** - * Construction. - */ - explicit MeshEvalPointOnEdge (const MeshKernel &rclM) : MeshEvaluation( rclM ) { } - /** - * Searches for points that lie on edge of triangle. - */ - bool Evaluate () override; - /** - * Returns the indices of all points on edge. - */ - std::vector GetPointIndices() const; - /** - * Returns the indices of all facets with an open edge on that a point lies. - */ - std::vector GetFacetIndices() const; + /** + * Construction. + */ + explicit MeshEvalPointOnEdge(const MeshKernel& rclM) + : MeshEvaluation(rclM) + {} + /** + * Searches for points that lie on edge of triangle. + */ + bool Evaluate() override; + /** + * Returns the indices of all points on edge. + */ + std::vector GetPointIndices() const; + /** + * Returns the indices of all facets with an open edge on that a point lies. + */ + std::vector GetFacetIndices() const; private: - std::vector pointsIndices; - std::vector facetsIndices; + std::vector pointsIndices; + std::vector facetsIndices; }; /** @@ -680,27 +765,30 @@ private: * @see MeshEvalPointOnEdge * @author Werner Mayer */ -class MeshExport MeshFixPointOnEdge : public MeshValidation +class MeshExport MeshFixPointOnEdge: public MeshValidation { public: - /** - * Construction. - */ - explicit MeshFixPointOnEdge (MeshKernel &rclM, bool fill = false) : MeshValidation( rclM ), fillBoundary(fill) { } - /** - * Removes points that lie on edges of triangles. - */ - bool Fixup () override; + /** + * Construction. + */ + explicit MeshFixPointOnEdge(MeshKernel& rclM, bool fill = false) + : MeshValidation(rclM) + , fillBoundary(fill) + {} + /** + * Removes points that lie on edges of triangles. + */ + bool Fixup() override; private: - void MarkBoundaries(const std::vector& facetsIndices); - void FindBoundaries(std::list >& borderList); - void FillBoundaries(const std::list >& borderList); + void MarkBoundaries(const std::vector& facetsIndices); + void FindBoundaries(std::list>& borderList); + void FillBoundaries(const std::list>& borderList); private: - bool fillBoundary; + bool fillBoundary; }; -} // namespace MeshCore +} // namespace MeshCore -#endif // MESH_DEGENERATION_H +#endif // MESH_DEGENERATION_H diff --git a/src/Mod/Mesh/App/Core/Elements.cpp b/src/Mod/Mesh/App/Core/Elements.cpp index 4cfa55398f..4f04abe768 100644 --- a/src/Mod/Mesh/App/Core/Elements.cpp +++ b/src/Mod/Mesh/App/Core/Elements.cpp @@ -22,15 +22,15 @@ #include "PreCompiled.h" -#include -#include #include #include +#include +#include -#include "Elements.h" #include "Algorithm.h" -#include "tritritest.h" +#include "Elements.h" #include "Utilities.h" +#include "tritritest.h" using namespace MeshCore; @@ -40,194 +40,213 @@ MeshPointArray::MeshPointArray(const MeshPointArray& ary) = default; MeshPointArray::MeshPointArray(MeshPointArray&& ary) = default; -PointIndex MeshPointArray::Get (const MeshPoint &rclPoint) +PointIndex MeshPointArray::Get(const MeshPoint& rclPoint) { - iterator clIter; + iterator clIter; - clIter = std::find(begin(), end(), rclPoint); - if (clIter != end()) - return clIter - begin(); - else - return POINT_INDEX_MAX; + clIter = std::find(begin(), end(), rclPoint); + if (clIter != end()) { + return clIter - begin(); + } + else { + return POINT_INDEX_MAX; + } } -PointIndex MeshPointArray::GetOrAddIndex (const MeshPoint &rclPoint) +PointIndex MeshPointArray::GetOrAddIndex(const MeshPoint& rclPoint) { - PointIndex ulIndex; + PointIndex ulIndex; - if ((ulIndex = Get(rclPoint)) == POINT_INDEX_MAX) - { - push_back(rclPoint); - return static_cast(size() - 1); - } - else - return ulIndex; + if ((ulIndex = Get(rclPoint)) == POINT_INDEX_MAX) { + push_back(rclPoint); + return static_cast(size() - 1); + } + else { + return ulIndex; + } } -void MeshPointArray::SetFlag (MeshPoint::TFlagType tF) const +void MeshPointArray::SetFlag(MeshPoint::TFlagType tF) const { - for (MeshPointArray::_TConstIterator i = begin(); i < end(); ++i) i->SetFlag(tF); + for (MeshPointArray::_TConstIterator i = begin(); i < end(); ++i) { + i->SetFlag(tF); + } } -void MeshPointArray::ResetFlag (MeshPoint::TFlagType tF) const +void MeshPointArray::ResetFlag(MeshPoint::TFlagType tF) const { - for (MeshPointArray::_TConstIterator i = begin(); i < end(); ++i) i->ResetFlag(tF); + for (MeshPointArray::_TConstIterator i = begin(); i < end(); ++i) { + i->ResetFlag(tF); + } } -void MeshPointArray::SetProperty (unsigned long ulVal) const +void MeshPointArray::SetProperty(unsigned long ulVal) const { - for (const auto & pP : *this) pP.SetProperty(ulVal); + for (const auto& pP : *this) { + pP.SetProperty(ulVal); + } } -void MeshPointArray::ResetInvalid () const +void MeshPointArray::ResetInvalid() const { - for (const auto & pP : *this) pP.ResetInvalid(); + for (const auto& pP : *this) { + pP.ResetInvalid(); + } } -MeshPointArray& MeshPointArray::operator = (const MeshPointArray &rclPAry) = default; +MeshPointArray& MeshPointArray::operator=(const MeshPointArray& rclPAry) = default; -MeshPointArray& MeshPointArray::operator = (MeshPointArray &&rclPAry) = default; +MeshPointArray& MeshPointArray::operator=(MeshPointArray&& rclPAry) = default; void MeshPointArray::Transform(const Base::Matrix4D& mat) { - for (auto & pP : *this) - mat.multVec(pP,pP); + for (auto& pP : *this) { + mat.multVec(pP, pP); + } } MeshFacetArray::MeshFacetArray(const MeshFacetArray& ary) = default; MeshFacetArray::MeshFacetArray(MeshFacetArray&& ary) = default; -void MeshFacetArray::Erase (_TIterator pIter) +void MeshFacetArray::Erase(_TIterator pIter) { - FacetIndex i, *pulN; - _TIterator pPass, pEnd; - FacetIndex ulInd = pIter - begin(); - erase(pIter); - pPass = begin(); - pEnd = end(); - while (pPass < pEnd) - { - for (i = 0; i < 3; i++) - { - pulN = &pPass->_aulNeighbours[i]; - if ((*pulN > ulInd) && (*pulN != FACET_INDEX_MAX)) - (*pulN)--; + FacetIndex i, *pulN; + _TIterator pPass, pEnd; + FacetIndex ulInd = pIter - begin(); + erase(pIter); + pPass = begin(); + pEnd = end(); + while (pPass < pEnd) { + for (i = 0; i < 3; i++) { + pulN = &pPass->_aulNeighbours[i]; + if ((*pulN > ulInd) && (*pulN != FACET_INDEX_MAX)) { + (*pulN)--; + } + } + pPass++; } - pPass++; - } } -void MeshFacetArray::TransposeIndices (PointIndex ulOrig, PointIndex ulNew) +void MeshFacetArray::TransposeIndices(PointIndex ulOrig, PointIndex ulNew) { - _TIterator pIter = begin(), pEnd = end(); + _TIterator pIter = begin(), pEnd = end(); - while (pIter < pEnd) - { - pIter->Transpose(ulOrig, ulNew); - ++pIter; - } + while (pIter < pEnd) { + pIter->Transpose(ulOrig, ulNew); + ++pIter; + } } -void MeshFacetArray::DecrementIndices (PointIndex ulIndex) +void MeshFacetArray::DecrementIndices(PointIndex ulIndex) { - _TIterator pIter = begin(), pEnd = end(); + _TIterator pIter = begin(), pEnd = end(); - while (pIter < pEnd) - { - pIter->Decrement(ulIndex); - ++pIter; - } + while (pIter < pEnd) { + pIter->Decrement(ulIndex); + ++pIter; + } } -void MeshFacetArray::SetFlag (MeshFacet::TFlagType tF) const +void MeshFacetArray::SetFlag(MeshFacet::TFlagType tF) const { - for (MeshFacetArray::_TConstIterator i = begin(); i < end(); ++i) i->SetFlag(tF); + for (MeshFacetArray::_TConstIterator i = begin(); i < end(); ++i) { + i->SetFlag(tF); + } } -void MeshFacetArray::ResetFlag (MeshFacet::TFlagType tF) const +void MeshFacetArray::ResetFlag(MeshFacet::TFlagType tF) const { - for (MeshFacetArray::_TConstIterator i = begin(); i < end(); ++i) i->ResetFlag(tF); + for (MeshFacetArray::_TConstIterator i = begin(); i < end(); ++i) { + i->ResetFlag(tF); + } } -void MeshFacetArray::SetProperty (unsigned long ulVal) const +void MeshFacetArray::SetProperty(unsigned long ulVal) const { - for (const auto & pF : *this) pF.SetProperty(ulVal); + for (const auto& pF : *this) { + pF.SetProperty(ulVal); + } } -void MeshFacetArray::ResetInvalid () const +void MeshFacetArray::ResetInvalid() const { - for (const auto & pF : *this) pF.ResetInvalid(); + for (const auto& pF : *this) { + pF.ResetInvalid(); + } } -MeshFacetArray& MeshFacetArray::operator = (const MeshFacetArray &rclFAry) = default; +MeshFacetArray& MeshFacetArray::operator=(const MeshFacetArray& rclFAry) = default; -MeshFacetArray& MeshFacetArray::operator = (MeshFacetArray &&rclFAry) = default; +MeshFacetArray& MeshFacetArray::operator=(MeshFacetArray&& rclFAry) = default; // ----------------------------------------------------------------- -bool MeshGeomEdge::ContainedByOrIntersectBoundingBox ( const Base::BoundBox3f &rclBB ) const +bool MeshGeomEdge::ContainedByOrIntersectBoundingBox(const Base::BoundBox3f& rclBB) const { - // Test whether all corner points of the Edge are on one of the 6 sides of the BB - if (!(GetBoundBox() && rclBB)) + // Test whether all corner points of the Edge are on one of the 6 sides of the BB + if (!(GetBoundBox() && rclBB)) { + return false; + } + + // Test whether Edge-BB is completely in BB + if (rclBB.IsInBox(GetBoundBox())) { + return true; + } + + // Test whether one of the corner points is in BB + for (const auto& pnt : _aclPoints) { + if (rclBB.IsInBox(pnt)) { + return true; + } + } + + // "real" test for cut + if (IntersectBoundingBox(rclBB)) { + return true; + } + return false; - - // Test whether Edge-BB is completely in BB - if (rclBB.IsInBox(GetBoundBox())) - return true; - - // Test whether one of the corner points is in BB - for (const auto& pnt : _aclPoints) - { - if (rclBB.IsInBox(pnt)) - return true; - } - - // "real" test for cut - if (IntersectBoundingBox(rclBB)) - return true; - - return false; } -Base::BoundBox3f MeshGeomEdge::GetBoundBox () const +Base::BoundBox3f MeshGeomEdge::GetBoundBox() const { - return {_aclPoints,2}; + return {_aclPoints, 2}; } -bool MeshGeomEdge::IntersectBoundingBox (const Base::BoundBox3f &rclBB) const +bool MeshGeomEdge::IntersectBoundingBox(const Base::BoundBox3f& rclBB) const { - const Base::Vector3f& rclP0 = _aclPoints[0]; - const Base::Vector3f& rclP1 = _aclPoints[1]; + const Base::Vector3f& rclP0 = _aclPoints[0]; + const Base::Vector3f& rclP1 = _aclPoints[1]; - Vector3 A(rclP0.x, rclP0.y, rclP0.z); - Vector3 B(rclP1.x, rclP1.y, rclP1.z); + Vector3 A(rclP0.x, rclP0.y, rclP0.z); + Vector3 B(rclP1.x, rclP1.y, rclP1.z); - Vector3 n = B - A; - float len = n.Length(); - n.Normalize(); - Vector3 p = 0.5f*(A + B); + Vector3 n = B - A; + float len = n.Length(); + n.Normalize(); + Vector3 p = 0.5f * (A + B); - Segment3 akSeg(p, n, 0.5f*len); + Segment3 akSeg(p, n, 0.5f * len); - Base::Vector3f clCenter = rclBB.GetCenter(); - Vector3 center(clCenter.x, clCenter.y, clCenter.z); - Vector3 axis0(1.0f, 0.0f, 0.0f); - Vector3 axis1(0.0f, 1.0f, 0.0f); - Vector3 axis2(0.0f, 0.0f, 1.0f); - float extent0 = 0.5f*rclBB.LengthX(); - float extent1 = 0.5f*rclBB.LengthY(); - float extent2 = 0.5f*rclBB.LengthZ(); + Base::Vector3f clCenter = rclBB.GetCenter(); + Vector3 center(clCenter.x, clCenter.y, clCenter.z); + Vector3 axis0(1.0f, 0.0f, 0.0f); + Vector3 axis1(0.0f, 1.0f, 0.0f); + Vector3 axis2(0.0f, 0.0f, 1.0f); + float extent0 = 0.5f * rclBB.LengthX(); + float extent1 = 0.5f * rclBB.LengthY(); + float extent2 = 0.5f * rclBB.LengthZ(); - Box3 kBox(center, axis0, axis1, axis2, extent0, extent1, extent2); + Box3 kBox(center, axis0, axis1, axis2, extent0, extent1, extent2); - IntrSegment3Box3 intrsectbox(akSeg, kBox, false); - return intrsectbox.Test(); + IntrSegment3Box3 intrsectbox(akSeg, kBox, false); + return intrsectbox.Test(); } -bool MeshGeomEdge::IntersectWithLine (const Base::Vector3f &rclPt, - const Base::Vector3f &rclDir, - Base::Vector3f &rclRes) const +bool MeshGeomEdge::IntersectWithLine(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + Base::Vector3f& rclRes) const { const float eps = 1e-06f; Base::Vector3f n = _aclPoints[1] - _aclPoints[0]; @@ -244,7 +263,7 @@ bool MeshGeomEdge::IntersectWithLine (const Base::Vector3f &rclPt, return true; } - return false; // no intersection possible + return false; // no intersection possible } // that's the normal of a helper plane and its base at _aclPoints @@ -252,8 +271,9 @@ bool MeshGeomEdge::IntersectWithLine (const Base::Vector3f &rclPt, // if the distance of rclPt to the plane is higher than eps then the // two lines are warped and there is no intersection possible - if (fabs(rclPt.DistanceToPlane(_aclPoints[0], normal)) > eps) + if (fabs(rclPt.DistanceToPlane(_aclPoints[0], normal)) > eps) { return false; + } // get a second helper plane and get the intersection with the line Base::Vector3f normal2 = normal.Cross(n); @@ -268,7 +288,7 @@ bool MeshGeomEdge::IntersectWithLine (const Base::Vector3f &rclPt, return dist2 + dist3 <= dist1 + eps; } -bool MeshGeomEdge::IsParallel(const MeshGeomEdge &edge) const +bool MeshGeomEdge::IsParallel(const MeshGeomEdge& edge) const { Base::Vector3f r(_aclPoints[1] - _aclPoints[0]); Base::Vector3f s(edge._aclPoints[1] - edge._aclPoints[0]); @@ -276,7 +296,7 @@ bool MeshGeomEdge::IsParallel(const MeshGeomEdge &edge) const return n.IsNull(); } -bool MeshGeomEdge::IsCollinear(const MeshGeomEdge &edge) const +bool MeshGeomEdge::IsCollinear(const MeshGeomEdge& edge) const { if (IsParallel(edge)) { Base::Vector3f r(_aclPoints[1] - _aclPoints[0]); @@ -287,7 +307,7 @@ bool MeshGeomEdge::IsCollinear(const MeshGeomEdge &edge) const return false; } -bool MeshGeomEdge::IntersectWithEdge (const MeshGeomEdge &edge, Base::Vector3f &res) const +bool MeshGeomEdge::IntersectWithEdge(const MeshGeomEdge& edge, Base::Vector3f& res) const { const float eps = 1e-06f; Base::Vector3f p(_aclPoints[0]); @@ -322,8 +342,9 @@ bool MeshGeomEdge::IntersectWithEdge (const MeshGeomEdge &edge, Base::Vector3f & float distance = q.DistanceToPlane(p, n); // lines are warped - if (fabs(distance) > eps) + if (fabs(distance) > eps) { return false; + } float t = d.Cross(s).Dot(n) / n.Sqr(); float u = d.Cross(r).Dot(n) / n.Sqr(); @@ -333,7 +354,7 @@ bool MeshGeomEdge::IntersectWithEdge (const MeshGeomEdge &edge, Base::Vector3f & }; if (is_in_range(t) && is_in_range(u)) { - res = p + t * r; // equal to q + u * s + res = p + t * r; // equal to q + u * s return true; } @@ -341,16 +362,17 @@ bool MeshGeomEdge::IntersectWithEdge (const MeshGeomEdge &edge, Base::Vector3f & } } -bool MeshGeomEdge::IntersectWithPlane (const Base::Vector3f &rclPt, - const Base::Vector3f &rclDir, - Base::Vector3f &rclRes) const +bool MeshGeomEdge::IntersectWithPlane(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + Base::Vector3f& rclRes) const { float dist1 = _aclPoints[0].DistanceToPlane(rclPt, rclDir); float dist2 = _aclPoints[1].DistanceToPlane(rclPt, rclDir); // either both points are below or above the plane - if (dist1 * dist2 >= 0.0f) + if (dist1 * dist2 >= 0.0f) { return false; + } Base::Vector3f u = _aclPoints[1] - _aclPoints[0]; Base::Vector3f b = rclPt - _aclPoints[0]; @@ -360,8 +382,7 @@ bool MeshGeomEdge::IntersectWithPlane (const Base::Vector3f &rclPt, return true; } -void MeshGeomEdge::ProjectPointToLine (const Base::Vector3f &rclPoint, - Base::Vector3f &rclProj) const +void MeshGeomEdge::ProjectPointToLine(const Base::Vector3f& rclPoint, Base::Vector3f& rclProj) const { Base::Vector3f pt1 = rclPoint - _aclPoints[0]; Base::Vector3f dir = _aclPoints[1] - _aclPoints[0]; @@ -370,8 +391,10 @@ void MeshGeomEdge::ProjectPointToLine (const Base::Vector3f &rclPoint, rclProj = rclPoint + vec; } -void MeshGeomEdge::ClosestPointsToLine(const Base::Vector3f &linePt, const Base::Vector3f &lineDir, - Base::Vector3f& rclPnt1, Base::Vector3f& rclPnt2) const +void MeshGeomEdge::ClosestPointsToLine(const Base::Vector3f& linePt, + const Base::Vector3f& lineDir, + Base::Vector3f& rclPnt1, + Base::Vector3f& rclPnt2) const { const float eps = 1e-06f; Base::Vector3f edgeDir = _aclPoints[1] - _aclPoints[0]; @@ -411,7 +434,7 @@ void MeshGeomEdge::ClosestPointsToLine(const Base::Vector3f &linePt, const Base: } } -bool MeshGeomEdge::IsPointOf (const Base::Vector3f &rclPoint, float fDistance) const +bool MeshGeomEdge::IsPointOf(const Base::Vector3f& rclPoint, float fDistance) const { float len2 = Base::DistanceP2(_aclPoints[0], _aclPoints[1]); if (len2 == 0.0f) { @@ -423,8 +446,9 @@ bool MeshGeomEdge::IsPointOf (const Base::Vector3f &rclPoint, float fDistance) c float dot = pXp1 * p2p1; float t = dot / len2; - if (t < 0.0f || t > 1.0f) + if (t < 0.0f || t > 1.0f) { return false; + } // point on the edge Base::Vector3f ptEdge = t * p2p1 + _aclPoints[0]; @@ -441,171 +465,177 @@ bool MeshGeomEdge::IsProjectionPointOf(const Base::Vector3f& point) const // ----------------------------------------------------------------- -MeshGeomFacet::MeshGeomFacet () - : _bNormalCalculated(false), - _ucFlag(0), _ulProp(0) -{ +MeshGeomFacet::MeshGeomFacet() + : _bNormalCalculated(false) + , _ucFlag(0) + , _ulProp(0) +{} + +MeshGeomFacet::MeshGeomFacet(const Base::Vector3f& v1, + const Base::Vector3f& v2, + const Base::Vector3f& v3) + : _bNormalCalculated(false) + , _ucFlag(0) + , _ulProp(0) +{ + _aclPoints[0] = v1; + _aclPoints[1] = v2; + _aclPoints[2] = v3; } -MeshGeomFacet::MeshGeomFacet (const Base::Vector3f &v1,const Base::Vector3f &v2,const Base::Vector3f &v3) - : _bNormalCalculated(false), - _ucFlag(0), - _ulProp(0) +bool MeshGeomFacet::IsPointOf(const Base::Vector3f& rclPoint, float fDistance) const { - _aclPoints[0] = v1; - _aclPoints[1] = v2; - _aclPoints[2] = v3; + if (DistancePlaneToPoint(rclPoint) > fDistance) { + return false; + } + + // force internal normal to be computed if not done yet + Base::Vector3f clNorm(GetNormal()), clProjPt(rclPoint), clEdge; + Base::Vector3f clP0(_aclPoints[0]), clP1(_aclPoints[1]), clP2(_aclPoints[2]); + float fLP, fLE; + + clNorm.Normalize(); + clProjPt.ProjectToPlane(_aclPoints[0], clNorm); + + + // Edge P0 --> P1 + clEdge = clP1 - clP0; + fLP = clProjPt.DistanceToLine(clP0, clEdge); + if (fLP > 0.0f) { + fLE = clP2.DistanceToLine(clP0, clEdge); + if (fLP <= fLE) { + if (clProjPt.DistanceToLine(clP2, clEdge) > fLE) { + return false; + } + } + else { + return false; + } + } + + // Edge P0 --> P2 + clEdge = clP2 - clP0; + fLP = clProjPt.DistanceToLine(clP0, clEdge); + if (fLP > 0.0f) { + fLE = clP1.DistanceToLine(clP0, clEdge); + if (fLP <= fLE) { + if (clProjPt.DistanceToLine(clP1, clEdge) > fLE) { + return false; + } + } + else { + return false; + } + } + + // Edge P1 --> P2 + clEdge = clP2 - clP1; + fLP = clProjPt.DistanceToLine(clP1, clEdge); + if (fLP > 0.0f) { + fLE = clP0.DistanceToLine(clP1, clEdge); + if (fLP <= fLE) { + if (clProjPt.DistanceToLine(clP0, clEdge) > fLE) { + return false; + } + } + else { + return false; + } + } + + return true; } - - -bool MeshGeomFacet::IsPointOf (const Base::Vector3f &rclPoint, float fDistance) const +bool MeshGeomFacet::IsPointOfFace(const Base::Vector3f& rclP, float fDistance) const { - if (DistancePlaneToPoint(rclPoint) > fDistance) - return false; + // more effective implementation than in MeshGeomFacet::IsPointOf + // + Base::Vector3f a(_aclPoints[0].x, _aclPoints[0].y, _aclPoints[0].z); + Base::Vector3f b(_aclPoints[1].x, _aclPoints[1].y, _aclPoints[1].z); + Base::Vector3f c(_aclPoints[2].x, _aclPoints[2].y, _aclPoints[2].z); + Base::Vector3f p(rclP); - // force internal normal to be computed if not done yet - Base::Vector3f clNorm(GetNormal()), clProjPt(rclPoint), clEdge; - Base::Vector3f clP0(_aclPoints[0]), clP1(_aclPoints[1]), clP2(_aclPoints[2]); - float fLP, fLE; + Base::Vector3f n = (b - a) % (c - a); + Base::Vector3f n1 = (a - p) % (b - p); + Base::Vector3f n2 = (c - p) % (a - p); + Base::Vector3f n3 = (b - p) % (c - p); - clNorm.Normalize(); - clProjPt.ProjectToPlane(_aclPoints[0], clNorm); - - - // Edge P0 --> P1 - clEdge = clP1 - clP0; - fLP = clProjPt.DistanceToLine(clP0, clEdge); - if (fLP > 0.0f) - { - fLE = clP2.DistanceToLine(clP0, clEdge); - if (fLP <= fLE) - { - if (clProjPt.DistanceToLine(clP2, clEdge) > fLE) + if (n * (p - a) > fDistance * n.Length()) { return false; } - else - return false; - } - // Edge P0 --> P2 - clEdge = clP2 - clP0; - fLP = clProjPt.DistanceToLine(clP0, clEdge); - if (fLP > 0.0f) - { - fLE = clP1.DistanceToLine(clP0, clEdge); - if (fLP <= fLE) - { - if (clProjPt.DistanceToLine(clP1, clEdge) > fLE) + if (n * (a - p) > fDistance * n.Length()) { return false; } - else - return false; - } - // Edge P1 --> P2 - clEdge = clP2 - clP1; - fLP = clProjPt.DistanceToLine(clP1, clEdge); - if (fLP > 0.0f) - { - fLE = clP0.DistanceToLine(clP1, clEdge); - if (fLP <= fLE) - { - if (clProjPt.DistanceToLine(clP0, clEdge) > fLE) + if (n * n1 <= 0.0f) { return false; } - else - return false; - } - return true; -} + if (n * n2 <= 0.0f) { + return false; + } -bool MeshGeomFacet::IsPointOfFace (const Base::Vector3f& rclP, float fDistance) const -{ - // more effective implementation than in MeshGeomFacet::IsPointOf - // - Base::Vector3f a(_aclPoints[0].x, _aclPoints[0].y, _aclPoints[0].z); - Base::Vector3f b(_aclPoints[1].x, _aclPoints[1].y, _aclPoints[1].z); - Base::Vector3f c(_aclPoints[2].x, _aclPoints[2].y, _aclPoints[2].z); - Base::Vector3f p(rclP); + if (n * n3 <= 0.0f) { + return false; + } - Base::Vector3f n = (b - a) % (c - a); - Base::Vector3f n1 = (a - p) % (b - p); - Base::Vector3f n2 = (c - p) % (a - p); - Base::Vector3f n3 = (b - p) % (c - p); - - if (n * (p - a) > fDistance * n.Length()) - return false; - - if (n * (a - p) > fDistance * n.Length()) - return false; - - if (n * n1 <= 0.0f) - return false; - - if (n * n2 <= 0.0f) - return false; - - if (n * n3 <= 0.0f) - return false; - - return true; + return true; } bool MeshGeomFacet::Weights(const Base::Vector3f& rclP, float& w0, float& w1, float& w2) const { - float fAreaABC = Area(); - float fAreaPBC = MeshGeomFacet(rclP,_aclPoints[1],_aclPoints[2]).Area(); - float fAreaPCA = MeshGeomFacet(rclP,_aclPoints[2],_aclPoints[0]).Area(); - float fAreaPAB = MeshGeomFacet(rclP,_aclPoints[0],_aclPoints[1]).Area(); + float fAreaABC = Area(); + float fAreaPBC = MeshGeomFacet(rclP, _aclPoints[1], _aclPoints[2]).Area(); + float fAreaPCA = MeshGeomFacet(rclP, _aclPoints[2], _aclPoints[0]).Area(); + float fAreaPAB = MeshGeomFacet(rclP, _aclPoints[0], _aclPoints[1]).Area(); - w0=fAreaPBC/fAreaABC; - w1=fAreaPCA/fAreaABC; - w2=fAreaPAB/fAreaABC; + w0 = fAreaPBC / fAreaABC; + w1 = fAreaPCA / fAreaABC; + w2 = fAreaPAB / fAreaABC; - return fabs(w0+w1+w2-1.0f)<0.001f; + return fabs(w0 + w1 + w2 - 1.0f) < 0.001f; } -void MeshGeomFacet::ProjectPointToPlane (const Base::Vector3f &rclPoint, Base::Vector3f &rclProj) const +void MeshGeomFacet::ProjectPointToPlane(const Base::Vector3f& rclPoint, + Base::Vector3f& rclProj) const { - rclPoint.ProjectToPlane(_aclPoints[0], GetNormal(), rclProj); + rclPoint.ProjectToPlane(_aclPoints[0], GetNormal(), rclProj); } -void MeshGeomFacet::ProjectFacetToPlane (MeshGeomFacet &rclFacet) const +void MeshGeomFacet::ProjectFacetToPlane(MeshGeomFacet& rclFacet) const { - // project facet 2 onto facet 1 - IntersectPlaneWithLine( rclFacet._aclPoints[0], GetNormal(), rclFacet._aclPoints[0] ); - IntersectPlaneWithLine( rclFacet._aclPoints[1], GetNormal(), rclFacet._aclPoints[1] ); - IntersectPlaneWithLine( rclFacet._aclPoints[2], GetNormal(), rclFacet._aclPoints[2] ); + // project facet 2 onto facet 1 + IntersectPlaneWithLine(rclFacet._aclPoints[0], GetNormal(), rclFacet._aclPoints[0]); + IntersectPlaneWithLine(rclFacet._aclPoints[1], GetNormal(), rclFacet._aclPoints[1]); + IntersectPlaneWithLine(rclFacet._aclPoints[2], GetNormal(), rclFacet._aclPoints[2]); } -void MeshGeomFacet::Enlarge (float fDist) +void MeshGeomFacet::Enlarge(float fDist) { - Base::Vector3f clM, clU, clV, clPNew[3]; - float fA, fD; - PointIndex i, ulP1, ulP2, ulP3; + Base::Vector3f clM, clU, clV, clPNew[3]; + float fA, fD; + PointIndex i, ulP1, ulP2, ulP3; - for (i = 0; i < 3; i++) - { - ulP1 = i; - ulP2 = (i + 1) % 3; - ulP3 = (i + 2) % 3; - clU = _aclPoints[ulP2] - _aclPoints[ulP1]; - clV = _aclPoints[ulP3] - _aclPoints[ulP1]; - clM = -(clU + clV); - fA = clM.GetAngle(-clU); - fD = fDist / float(sin(fA)); - clM.Normalize(); - clM.Scale(fD, fD, fD); - clPNew[ulP1] = _aclPoints[ulP1] + clM; - } + for (i = 0; i < 3; i++) { + ulP1 = i; + ulP2 = (i + 1) % 3; + ulP3 = (i + 2) % 3; + clU = _aclPoints[ulP2] - _aclPoints[ulP1]; + clV = _aclPoints[ulP3] - _aclPoints[ulP1]; + clM = -(clU + clV); + fA = clM.GetAngle(-clU); + fD = fDist / float(sin(fA)); + clM.Normalize(); + clM.Scale(fD, fD, fD); + clPNew[ulP1] = _aclPoints[ulP1] + clM; + } - _aclPoints[0] = clPNew[0]; - _aclPoints[1] = clPNew[1]; - _aclPoints[2] = clPNew[2]; + _aclPoints[0] = clPNew[0]; + _aclPoints[1] = clPNew[1]; + _aclPoints[2] = clPNew[2]; } bool MeshGeomFacet::IsDegenerated(float epsilon) const @@ -635,99 +665,110 @@ bool MeshGeomFacet::IsDegenerated(float epsilon) const Base::Vector3d v = p3 - p1; double eps = static_cast(epsilon); - double uu = u*u; - if (uu <= eps) + double uu = u * u; + if (uu <= eps) { return true; - double vv = v*v; - if (vv <= eps) + } + double vv = v * v; + if (vv <= eps) { return true; - double uv = u*v; - double crosssqr = uu*vv-uv*uv; - if (crosssqr <= eps*std::max(uu,vv)) + } + double uv = u * v; + double crosssqr = uu * vv - uv * uv; + if (crosssqr <= eps * std::max(uu, vv)) { return true; + } return false; } bool MeshGeomFacet::IsDeformed(float fCosOfMinAngle, float fCosOfMaxAngle) const { float fCosAngle; - Base::Vector3f u,v; + Base::Vector3f u, v; - for (int i=0; i<3; i++) { - u = _aclPoints[(i+1)%3]-_aclPoints[i]; - v = _aclPoints[(i+2)%3]-_aclPoints[i]; + for (int i = 0; i < 3; i++) { + u = _aclPoints[(i + 1) % 3] - _aclPoints[i]; + v = _aclPoints[(i + 2) % 3] - _aclPoints[i]; u.Normalize(); v.Normalize(); fCosAngle = u * v; - if (fCosAngle > fCosOfMinAngle || fCosAngle < fCosOfMaxAngle) + if (fCosAngle > fCosOfMinAngle || fCosAngle < fCosOfMaxAngle) { return true; + } } return false; } -bool MeshGeomFacet::IntersectBoundingBox ( const Base::BoundBox3f &rclBB ) const +bool MeshGeomFacet::IntersectBoundingBox(const Base::BoundBox3f& rclBB) const { - // the triangle's corner points - const Base::Vector3f& v0 = _aclPoints[0]; - const Base::Vector3f& v1 = _aclPoints[1]; - const Base::Vector3f& v2 = _aclPoints[2]; + // the triangle's corner points + const Base::Vector3f& v0 = _aclPoints[0]; + const Base::Vector3f& v1 = _aclPoints[1]; + const Base::Vector3f& v2 = _aclPoints[2]; - // first check if at least one point is inside the box - if ( rclBB.IsInBox( v0 ) || rclBB.IsInBox( v1 ) || rclBB.IsInBox( v2 ) ) - return true; + // first check if at least one point is inside the box + if (rclBB.IsInBox(v0) || rclBB.IsInBox(v1) || rclBB.IsInBox(v2)) { + return true; + } - // edge lengths - float len0 = (v0-v1).Length(); - float len1 = (v1-v2).Length(); - float len2 = (v2-v0).Length(); + // edge lengths + float len0 = (v0 - v1).Length(); + float len1 = (v1 - v2).Length(); + float len2 = (v2 - v0).Length(); - // Build up the line segments - Vector3 p0(0.5f*(v0.x+v1.x), 0.5f*(v0.y+v1.y), 0.5f*(v0.z+v1.z)); - Vector3 p1(0.5f*(v1.x+v2.x), 0.5f*(v1.y+v2.y), 0.5f*(v1.z+v2.z)); - Vector3 p2(0.5f*(v2.x+v0.x), 0.5f*(v2.y+v0.y), 0.5f*(v2.z+v0.z)); + // Build up the line segments + Vector3 p0(0.5f * (v0.x + v1.x), 0.5f * (v0.y + v1.y), 0.5f * (v0.z + v1.z)); + Vector3 p1(0.5f * (v1.x + v2.x), 0.5f * (v1.y + v2.y), 0.5f * (v1.z + v2.z)); + Vector3 p2(0.5f * (v2.x + v0.x), 0.5f * (v2.y + v0.y), 0.5f * (v2.z + v0.z)); - Vector3 d0(v1.x - v0.x, v1.y - v0.y, v1.z - v0.z); - d0.Normalize(); - Vector3 d1(v2.x - v1.x, v2.y - v1.y, v2.z - v1.z); - d1.Normalize(); - Vector3 d2(v0.x - v2.x, v0.y - v2.y, v0.z - v2.z); - d2.Normalize(); + Vector3 d0(v1.x - v0.x, v1.y - v0.y, v1.z - v0.z); + d0.Normalize(); + Vector3 d1(v2.x - v1.x, v2.y - v1.y, v2.z - v1.z); + d1.Normalize(); + Vector3 d2(v0.x - v2.x, v0.y - v2.y, v0.z - v2.z); + d2.Normalize(); - Segment3 akSeg0(p0, d0, len0/2.0f ); - Segment3 akSeg1(p1, d1, len1/2.0f); - Segment3 akSeg2(p2, d2, len2/2.0f); + Segment3 akSeg0(p0, d0, len0 / 2.0f); + Segment3 akSeg1(p1, d1, len1 / 2.0f); + Segment3 akSeg2(p2, d2, len2 / 2.0f); - // Build up the box - Base::Vector3f clCenter = rclBB.GetCenter(); - Vector3 center(clCenter.x, clCenter.y, clCenter.z); - Vector3 axis0(1.0f, 0.0f, 0.0f); - Vector3 axis1(0.0f, 1.0f, 0.0f); - Vector3 axis2(0.0f, 0.0f, 1.0f); - float extent0 = 0.5f*rclBB.LengthX(); - float extent1 = 0.5f*rclBB.LengthY(); - float extent2 = 0.5f*rclBB.LengthZ(); + // Build up the box + Base::Vector3f clCenter = rclBB.GetCenter(); + Vector3 center(clCenter.x, clCenter.y, clCenter.z); + Vector3 axis0(1.0f, 0.0f, 0.0f); + Vector3 axis1(0.0f, 1.0f, 0.0f); + Vector3 axis2(0.0f, 0.0f, 1.0f); + float extent0 = 0.5f * rclBB.LengthX(); + float extent1 = 0.5f * rclBB.LengthY(); + float extent2 = 0.5f * rclBB.LengthZ(); - Box3 akBox(center, axis0, axis1, axis2, extent0, extent1, extent2); + Box3 akBox(center, axis0, axis1, axis2, extent0, extent1, extent2); - // Check for intersection of line segments and box - IntrSegment3Box3 akSec0(akSeg0, akBox, false); - if ( akSec0.Test() ) - return true; - IntrSegment3Box3 akSec1(akSeg1, akBox, false); - if ( akSec1.Test() ) - return true; - IntrSegment3Box3 akSec2(akSeg2, akBox, false); - if ( akSec2.Test() ) - return true; + // Check for intersection of line segments and box + IntrSegment3Box3 akSec0(akSeg0, akBox, false); + if (akSec0.Test()) { + return true; + } + IntrSegment3Box3 akSec1(akSeg1, akBox, false); + if (akSec1.Test()) { + return true; + } + IntrSegment3Box3 akSec2(akSeg2, akBox, false); + if (akSec2.Test()) { + return true; + } - // no intersection - return false; + // no intersection + return false; } -bool MeshGeomFacet::IntersectWithPlane (const Base::Vector3f &rclBase, const Base::Vector3f &rclNormal, Base::Vector3f &rclP1, Base::Vector3f &rclP2) const +bool MeshGeomFacet::IntersectWithPlane(const Base::Vector3f& rclBase, + const Base::Vector3f& rclNormal, + Base::Vector3f& rclP1, + Base::Vector3f& rclP2) const { const float eps = 1e-06f; @@ -757,14 +798,14 @@ bool MeshGeomFacet::IntersectWithPlane (const Base::Vector3f &rclBase, const Bas } // edge lengths - float len0 = (v0-v1).Length(); - float len1 = (v1-v2).Length(); - float len2 = (v2-v0).Length(); + float len0 = (v0 - v1).Length(); + float len1 = (v1 - v2).Length(); + float len2 = (v2 - v0).Length(); // Build up the line segments - Vector3 p0(0.5f*(v0.x+v1.x), 0.5f*(v0.y+v1.y), 0.5f*(v0.z+v1.z)); - Vector3 p1(0.5f*(v1.x+v2.x), 0.5f*(v1.y+v2.y), 0.5f*(v1.z+v2.z)); - Vector3 p2(0.5f*(v2.x+v0.x), 0.5f*(v2.y+v0.y), 0.5f*(v2.z+v0.z)); + Vector3 p0(0.5f * (v0.x + v1.x), 0.5f * (v0.y + v1.y), 0.5f * (v0.z + v1.z)); + Vector3 p1(0.5f * (v1.x + v2.x), 0.5f * (v1.y + v2.y), 0.5f * (v1.z + v2.z)); + Vector3 p2(0.5f * (v2.x + v0.x), 0.5f * (v2.y + v0.y), 0.5f * (v2.z + v0.z)); Vector3 d0(v1.x - v0.x, v1.y - v0.y, v1.z - v0.z); d0.Normalize(); @@ -773,9 +814,9 @@ bool MeshGeomFacet::IntersectWithPlane (const Base::Vector3f &rclBase, const Bas Vector3 d2(v0.x - v2.x, v0.y - v2.y, v0.z - v2.z); d2.Normalize(); - Segment3 akSeg0(p0, d0, len0/2.0f ); - Segment3 akSeg1(p1, d1, len1/2.0f); - Segment3 akSeg2(p2, d2, len2/2.0f); + Segment3 akSeg0(p0, d0, len0 / 2.0f); + Segment3 akSeg1(p1, d1, len1 / 2.0f); + Segment3 akSeg2(p2, d2, len2 / 2.0f); // Build up the plane Vector3 p(rclBase.x, rclBase.y, rclBase.z); @@ -821,26 +862,26 @@ bool MeshGeomFacet::IntersectWithPlane (const Base::Vector3f &rclBase, const Bas // check for arbitrary intersections if (test0.Find()) { intr = p0 + test0.GetSegmentT() * d0; - rclP1.Set( intr[0], intr[1], intr[2]); + rclP1.Set(intr[0], intr[1], intr[2]); if (test1.Find()) { intr = p1 + test1.GetSegmentT() * d1; - rclP2.Set( intr[0], intr[1], intr[2]); + rclP2.Set(intr[0], intr[1], intr[2]); return true; } else if (test2.Find()) { intr = p2 + test2.GetSegmentT() * d2; - rclP2.Set( intr[0], intr[1], intr[2]); + rclP2.Set(intr[0], intr[1], intr[2]); return true; } } else if (test1.Find()) { intr = p1 + test1.GetSegmentT() * d1; - rclP1.Set( intr[0], intr[1], intr[2]); + rclP1.Set(intr[0], intr[1], intr[2]); if (test2.Find()) { intr = p2 + test2.GetSegmentT() * d2; - rclP2.Set( intr[0], intr[1], intr[2]); + rclP2.Set(intr[0], intr[1], intr[2]); return true; } } @@ -848,7 +889,10 @@ bool MeshGeomFacet::IntersectWithPlane (const Base::Vector3f &rclBase, const Bas return false; } -bool MeshGeomFacet::Foraminate (const Base::Vector3f &P, const Base::Vector3f &dir, Base::Vector3f &I, float fMaxAngle) const +bool MeshGeomFacet::Foraminate(const Base::Vector3f& P, + const Base::Vector3f& dir, + Base::Vector3f& I, + float fMaxAngle) const { const float eps = 1e-06f; Base::Vector3f n = this->GetNormal(); @@ -856,23 +900,25 @@ bool MeshGeomFacet::Foraminate (const Base::Vector3f &P, const Base::Vector3f &d // check angle between facet normal and the line direction, FLOAT_MAX is // returned for degenerated facets float fAngle = dir.GetAngle(n); - if (fAngle > fMaxAngle) + if (fAngle > fMaxAngle) { return false; + } float nn = n * n; float nd = n * dir; float dd = dir * dir; // the line mustn't be parallel to the triangle - if ((nd * nd) <= (eps * dd * nn)) + if ((nd * nd) <= (eps * dd * nn)) { return false; + } Base::Vector3f u = this->_aclPoints[1] - this->_aclPoints[0]; Base::Vector3f v = this->_aclPoints[2] - this->_aclPoints[0]; Base::Vector3f w0 = P - this->_aclPoints[0]; float r = -(n * w0) / nd; - Base::Vector3f w = w0 + r * dir; + Base::Vector3f w = w0 + r * dir; float uu = u * u; float uv = u * v; @@ -881,8 +927,8 @@ bool MeshGeomFacet::Foraminate (const Base::Vector3f &P, const Base::Vector3f &d float wv = w * v; float det = float(fabs((uu * vv) - (uv * uv))); - float s = (vv * wu) - (uv * wv); - float t = (uu * wv) - (uv * wu); + float s = (vv * wu) - (uv * wv); + float t = (uu * wv) - (uv * wu); // is the intersection point inside the triangle? if ((s >= 0.0f) && (t >= 0.0f) && ((s + t) <= det)) { @@ -893,138 +939,140 @@ bool MeshGeomFacet::Foraminate (const Base::Vector3f &P, const Base::Vector3f &d return false; } -bool MeshGeomFacet::IntersectPlaneWithLine (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, Base::Vector3f &rclRes) const +bool MeshGeomFacet::IntersectPlaneWithLine(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + Base::Vector3f& rclRes) const { - // calculate the intersection of the straight line <-> plane - if ( fabs(rclDir * GetNormal()) < 1e-3f ) - return false; // line and plane are parallel - - float s = ( ( GetGravityPoint() - rclPt ) * GetNormal() ) - / ( rclDir * GetNormal() ); - rclRes = rclPt + s * rclDir; - - return true; -} - -bool MeshGeomFacet::IntersectWithLine (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, Base::Vector3f &rclRes) const -{ - if ( !IntersectPlaneWithLine( rclPt, rclDir, rclRes ) ) - return false; // line and plane are parallel - // Check if the intersection point is inside the facet - return IsPointOfFace(rclRes, 1e-03f); -} - -float MeshGeomFacet::DistanceToLineSegment (const Base::Vector3f &rclP1, const Base::Vector3f &rclP2) const -{ - // line segment - Vector3 A(rclP1.x, rclP1.y, rclP1.z); - Vector3 B(rclP2.x, rclP2.y, rclP2.z); - - Vector3 n = B - A; - float len = n.Length(); - n.Normalize(); - Vector3 p = 0.5f*(A + B); - - Segment3 akSeg(p, n, 0.5f*len); - - // triangle - Vector3 akF0(_aclPoints[0].x, _aclPoints[0].y, _aclPoints[0].z); - Vector3 akF1(_aclPoints[1].x, _aclPoints[1].y, _aclPoints[1].z); - Vector3 akF2(_aclPoints[2].x, _aclPoints[2].y, _aclPoints[2].z); - - Triangle3 akTria(akF0, akF1, akF2); - - DistSegment3Triangle3 akDistSegTria(akSeg, akTria); - return akDistSegTria.Get(); -} - -float MeshGeomFacet::DistanceToPoint (const Base::Vector3f &rclPt, Base::Vector3f &rclNt) const -{ - Vector3 akPt(rclPt.x, rclPt.y, rclPt.z); - Vector3 akF0(_aclPoints[0].x, _aclPoints[0].y, _aclPoints[0].z); - Vector3 akF1(_aclPoints[1].x, _aclPoints[1].y, _aclPoints[1].z); - Vector3 akF2(_aclPoints[2].x, _aclPoints[2].y, _aclPoints[2].z); - - Triangle3 akTria(akF0, akF1, akF2); - DistVector3Triangle3 akDistPtTria(akPt, akTria); - - float fDist = akDistPtTria.Get(); - - // get nearest point of the facet - Vector3 akNt = akDistPtTria.GetClosestPoint1(); - rclNt.Set(akNt.X(), akNt.Y(), akNt.Z()); - - return fDist; -} - -void MeshGeomFacet::SubSample (float fStep, std::vector &rclPoints) const -{ - std::vector clPoints; - Base::Vector3f A = _aclPoints[0]; - Base::Vector3f B = _aclPoints[1]; - Base::Vector3f C = _aclPoints[2]; - Base::Vector3f clVecAB(B - A); - Base::Vector3f clVecAC(C - A); - Base::Vector3f clVecBC(C - B); - - // longest axis corresponds to AB - float fLenAB = clVecAB.Length(); - float fLenAC = clVecAC.Length(); - float fLenBC = clVecBC.Length(); - - if (fLenAC > fLenAB) - { - std::swap(B, C); - std::swap(fLenAB, fLenAC); - } - if (fLenBC > fLenAB) - { - std::swap(A, C); - std::swap(fLenBC, fLenAB); - } - - clVecAB = (B - A); - clVecAC = (C - A); - clVecBC = (C - B); - Base::Vector3f clVecABNorm(clVecAB); - Base::Vector3f clVecHNorm((clVecAB % clVecAC) % clVecAB); - clVecABNorm.Normalize(); - clVecHNorm.Normalize(); - - float bx = fLenAB; - float cy = float(sin(clVecAB.GetAngle(clVecAC)) * fLenAC); - float cx = float(sqrt(fabs(fLenAC * fLenAC - cy * cy))); - - float fDetABC = bx*cy; - - for (float px = (fStep / 2.0f); px < fLenAB; px += fStep) - { - for (float py = (fStep / 2.0f); py < cy; py += fStep) - { - float u = (bx*cy + cx*py - px*cy - bx*py) / fDetABC; - float v = (px*cy - cx*py) / fDetABC; - float w = (bx*py) / fDetABC; - - if ((u >= 0.0f) && (v >= 0.0f) && (w >= 0.0f) && ((u + v) < 1.0f)) - { - // rclPoints.push_back(CBase::Vector3f(u*A + v*B + w*C)); - Base::Vector3f clV = A + (px * clVecABNorm) + (py * clVecHNorm); - clPoints.push_back(clV); - - } - else - break; + // calculate the intersection of the straight line <-> plane + if (fabs(rclDir * GetNormal()) < 1e-3f) { + return false; // line and plane are parallel } - } - // if couldn't subsample the facet take gravity center - if (clPoints.empty()) - clPoints.push_back(this->GetGravityPoint()); + float s = ((GetGravityPoint() - rclPt) * GetNormal()) / (rclDir * GetNormal()); + rclRes = rclPt + s * rclDir; - rclPoints.insert(rclPoints.end(), clPoints.begin(), clPoints.end()); + return true; } -bool MeshGeomFacet::IsCoplanar(const MeshGeomFacet &facet) const +bool MeshGeomFacet::IntersectWithLine(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + Base::Vector3f& rclRes) const +{ + if (!IntersectPlaneWithLine(rclPt, rclDir, rclRes)) { + return false; // line and plane are parallel + } + // Check if the intersection point is inside the facet + return IsPointOfFace(rclRes, 1e-03f); +} + +float MeshGeomFacet::DistanceToLineSegment(const Base::Vector3f& rclP1, + const Base::Vector3f& rclP2) const +{ + // line segment + Vector3 A(rclP1.x, rclP1.y, rclP1.z); + Vector3 B(rclP2.x, rclP2.y, rclP2.z); + + Vector3 n = B - A; + float len = n.Length(); + n.Normalize(); + Vector3 p = 0.5f * (A + B); + + Segment3 akSeg(p, n, 0.5f * len); + + // triangle + Vector3 akF0(_aclPoints[0].x, _aclPoints[0].y, _aclPoints[0].z); + Vector3 akF1(_aclPoints[1].x, _aclPoints[1].y, _aclPoints[1].z); + Vector3 akF2(_aclPoints[2].x, _aclPoints[2].y, _aclPoints[2].z); + + Triangle3 akTria(akF0, akF1, akF2); + + DistSegment3Triangle3 akDistSegTria(akSeg, akTria); + return akDistSegTria.Get(); +} + +float MeshGeomFacet::DistanceToPoint(const Base::Vector3f& rclPt, Base::Vector3f& rclNt) const +{ + Vector3 akPt(rclPt.x, rclPt.y, rclPt.z); + Vector3 akF0(_aclPoints[0].x, _aclPoints[0].y, _aclPoints[0].z); + Vector3 akF1(_aclPoints[1].x, _aclPoints[1].y, _aclPoints[1].z); + Vector3 akF2(_aclPoints[2].x, _aclPoints[2].y, _aclPoints[2].z); + + Triangle3 akTria(akF0, akF1, akF2); + DistVector3Triangle3 akDistPtTria(akPt, akTria); + + float fDist = akDistPtTria.Get(); + + // get nearest point of the facet + Vector3 akNt = akDistPtTria.GetClosestPoint1(); + rclNt.Set(akNt.X(), akNt.Y(), akNt.Z()); + + return fDist; +} + +void MeshGeomFacet::SubSample(float fStep, std::vector& rclPoints) const +{ + std::vector clPoints; + Base::Vector3f A = _aclPoints[0]; + Base::Vector3f B = _aclPoints[1]; + Base::Vector3f C = _aclPoints[2]; + Base::Vector3f clVecAB(B - A); + Base::Vector3f clVecAC(C - A); + Base::Vector3f clVecBC(C - B); + + // longest axis corresponds to AB + float fLenAB = clVecAB.Length(); + float fLenAC = clVecAC.Length(); + float fLenBC = clVecBC.Length(); + + if (fLenAC > fLenAB) { + std::swap(B, C); + std::swap(fLenAB, fLenAC); + } + if (fLenBC > fLenAB) { + std::swap(A, C); + std::swap(fLenBC, fLenAB); + } + + clVecAB = (B - A); + clVecAC = (C - A); + clVecBC = (C - B); + Base::Vector3f clVecABNorm(clVecAB); + Base::Vector3f clVecHNorm((clVecAB % clVecAC) % clVecAB); + clVecABNorm.Normalize(); + clVecHNorm.Normalize(); + + float bx = fLenAB; + float cy = float(sin(clVecAB.GetAngle(clVecAC)) * fLenAC); + float cx = float(sqrt(fabs(fLenAC * fLenAC - cy * cy))); + + float fDetABC = bx * cy; + + for (float px = (fStep / 2.0f); px < fLenAB; px += fStep) { + for (float py = (fStep / 2.0f); py < cy; py += fStep) { + float u = (bx * cy + cx * py - px * cy - bx * py) / fDetABC; + float v = (px * cy - cx * py) / fDetABC; + float w = (bx * py) / fDetABC; + + if ((u >= 0.0f) && (v >= 0.0f) && (w >= 0.0f) && ((u + v) < 1.0f)) { + // rclPoints.push_back(CBase::Vector3f(u*A + v*B + w*C)); + Base::Vector3f clV = A + (px * clVecABNorm) + (py * clVecHNorm); + clPoints.push_back(clV); + } + else { + break; + } + } + } + + // if couldn't subsample the facet take gravity center + if (clPoints.empty()) { + clPoints.push_back(this->GetGravityPoint()); + } + + rclPoints.insert(rclPoints.end(), clPoints.begin(), clPoints.end()); +} + +bool MeshGeomFacet::IsCoplanar(const MeshGeomFacet& facet) const { const float eps = 1e-06f; const float unit = 0.9995f; @@ -1038,22 +1086,22 @@ bool MeshGeomFacet::IsCoplanar(const MeshGeomFacet &facet) const * http://www.acm.org/jgt/papers/Moller97/tritri.html * http://www.cs.lth.se/home/Tomas_Akenine_Moller/code/ */ -bool MeshGeomFacet::IntersectWithFacet(const MeshGeomFacet &rclFacet) const +bool MeshGeomFacet::IntersectWithFacet(const MeshGeomFacet& rclFacet) const { - float V[3][3], U[3][3]; - for (int i = 0; i < 3; i++) - { - V[i][0] = _aclPoints[i].x; - V[i][1] = _aclPoints[i].y; - V[i][2] = _aclPoints[i].z; - U[i][0] = rclFacet._aclPoints[i].x; - U[i][1] = rclFacet._aclPoints[i].y; - U[i][2] = rclFacet._aclPoints[i].z; - } + float V[3][3], U[3][3]; + for (int i = 0; i < 3; i++) { + V[i][0] = _aclPoints[i].x; + V[i][1] = _aclPoints[i].y; + V[i][2] = _aclPoints[i].z; + U[i][0] = rclFacet._aclPoints[i].x; + U[i][1] = rclFacet._aclPoints[i].y; + U[i][2] = rclFacet._aclPoints[i].z; + } - if (tri_tri_intersect(V[0], V[1], V[2], U[0], U[1], U[2]) == 0) - return false; // no intersections - return true; + if (tri_tri_intersect(V[0], V[1], V[2], U[0], U[1], U[2]) == 0) { + return false; // no intersections + } + return true; } /** @@ -1061,9 +1109,9 @@ bool MeshGeomFacet::IntersectWithFacet(const MeshGeomFacet &rclFacet) const * http://www.acm.org/jgt/papers/Moller97/tritri.html * http://www.cs.lth.se/home/Tomas_Akenine_Moller/code/ */ -int MeshGeomFacet::IntersectWithFacet (const MeshGeomFacet& rclFacet, - Base::Vector3f& rclPt0, - Base::Vector3f& rclPt1) const +int MeshGeomFacet::IntersectWithFacet(const MeshGeomFacet& rclFacet, + Base::Vector3f& rclPt0, + Base::Vector3f& rclPt1) const { // Note: tri_tri_intersect_with_isection() does not return line of // intersection when triangles are coplanar. See tritritest.h:18 and 658. @@ -1071,9 +1119,9 @@ int MeshGeomFacet::IntersectWithFacet (const MeshGeomFacet& rclFacet, // Since tri_tri_intersect_with_isection may return garbage values try to get // sensible values with edge/edge intersections std::vector intersections; - for (short i=0; i<3; i++) { + for (short i = 0; i < 3; i++) { MeshGeomEdge edge1 = GetEdge(i); - for (short j=0; j<3; j++) { + for (short j = 0; j < 3; j++) { MeshGeomEdge edge2 = rclFacet.GetEdge(j); Base::Vector3f point; if (edge1.IntersectWithEdge(edge2, point)) { @@ -1102,8 +1150,7 @@ int MeshGeomFacet::IntersectWithFacet (const MeshGeomFacet& rclFacet, int coplanar = 0; float isectpt1[3], isectpt2[3]; - for (int i = 0; i < 3; i++) - { + for (int i = 0; i < 3; i++) { V[i][0] = _aclPoints[i].x; V[i][1] = _aclPoints[i].y; V[i][2] = _aclPoints[i].z; @@ -1112,12 +1159,25 @@ int MeshGeomFacet::IntersectWithFacet (const MeshGeomFacet& rclFacet, U[i][2] = rclFacet._aclPoints[i].z; } - if (tri_tri_intersect_with_isectline(V[0], V[1], V[2], U[0], U[1], U[2], - &coplanar, isectpt1, isectpt2) == 0) - return 0; // no intersections + if (tri_tri_intersect_with_isectline(V[0], + V[1], + V[2], + U[0], + U[1], + U[2], + &coplanar, + isectpt1, + isectpt2) + == 0) { + return 0; // no intersections + } - rclPt0.x = isectpt1[0]; rclPt0.y = isectpt1[1]; rclPt0.z = isectpt1[2]; - rclPt1.x = isectpt2[0]; rclPt1.y = isectpt2[1]; rclPt1.z = isectpt2[2]; + rclPt0.x = isectpt1[0]; + rclPt0.y = isectpt1[1]; + rclPt0.z = isectpt1[2]; + rclPt1.x = isectpt2[0]; + rclPt1.y = isectpt2[1]; + rclPt1.z = isectpt2[2]; // With extremely acute-angled triangles it may happen that the algorithm // claims an intersection but the intersection points are far outside the @@ -1125,37 +1185,43 @@ int MeshGeomFacet::IntersectWithFacet (const MeshGeomFacet& rclFacet, // are inside the bounding boxes of both triangles. Base::BoundBox3f box1 = this->GetBoundBox(); box1.Enlarge(0.001f); - if (!box1.IsInBox(rclPt0) || !box1.IsInBox(rclPt1)) + if (!box1.IsInBox(rclPt0) || !box1.IsInBox(rclPt1)) { return 0; + } Base::BoundBox3f box2 = rclFacet.GetBoundBox(); box2.Enlarge(0.001f); - if (!box2.IsInBox(rclPt0) || !box2.IsInBox(rclPt1)) + if (!box2.IsInBox(rclPt0) || !box2.IsInBox(rclPt1)) { return 0; + } // Note: The algorithm delivers sometimes false-positives, i.e. it claims // that the two triangles intersect but they don't. It seems that this bad // behaviour occurs if the triangles are nearly co-planar float mult = fabs(this->GetNormal() * rclFacet.GetNormal()); if (rclPt0 == rclPt1) { - if (mult < 0.995f) // not co-planar, thus no test needed + if (mult < 0.995f) { // not co-planar, thus no test needed return 1; - if (this->IsPointOf(rclPt0) && rclFacet.IsPointOf(rclPt0)) + } + if (this->IsPointOf(rclPt0) && rclFacet.IsPointOf(rclPt0)) { return 1; + } } else { - if (mult < 0.995f) // not co-planar, thus no test needed + if (mult < 0.995f) { // not co-planar, thus no test needed return 2; - if (this->IsPointOf(rclPt0) && rclFacet.IsPointOf(rclPt0) && - this->IsPointOf(rclPt1) && rclFacet.IsPointOf(rclPt1)) + } + if (this->IsPointOf(rclPt0) && rclFacet.IsPointOf(rclPt0) && this->IsPointOf(rclPt1) + && rclFacet.IsPointOf(rclPt1)) { return 2; + } } // the intersection algorithm delivered a false-positive return 0; } -bool MeshGeomFacet::IsPointOf (const Base::Vector3f &P) const +bool MeshGeomFacet::IsPointOf(const Base::Vector3f& P) const { Base::Vector3d p1 = Base::convertTo(this->_aclPoints[0]); Base::Vector3d p2 = Base::convertTo(this->_aclPoints[1]); @@ -1177,13 +1243,13 @@ bool MeshGeomFacet::IsPointOf (const Base::Vector3f &P) const // negative values for s or t. This e.g. can happen if the point lies // at the border of the facet. And as det could also become very small // we need an adaptive tolerance. - const double eps=std::min(1.0e-6, det*det); + const double eps = std::min(1.0e-6, det * det); - double s = (vv * wu) - (uv * wv); - double t = (uu * wv) - (uv * wu); + double s = (vv * wu) - (uv * wv); + double t = (uu * wv) - (uv * wu); // is the point inside the triangle? - if ((s >= -eps) && (t >= -eps) && ((s + t) <= det+eps)) { + if ((s >= -eps) && (t >= -eps) && ((s + t) <= det + eps)) { return true; } @@ -1192,306 +1258,315 @@ bool MeshGeomFacet::IsPointOf (const Base::Vector3f &P) const float MeshGeomFacet::CenterOfInscribedCircle(Base::Vector3f& rclCenter) const { - const Base::Vector3f& p0 = _aclPoints[0]; - const Base::Vector3f& p1 = _aclPoints[1]; - const Base::Vector3f& p2 = _aclPoints[2]; + const Base::Vector3f& p0 = _aclPoints[0]; + const Base::Vector3f& p1 = _aclPoints[1]; + const Base::Vector3f& p2 = _aclPoints[2]; - float a = Base::Distance(p1,p2); - float b = Base::Distance(p2,p0); - float c = Base::Distance(p0,p1); + float a = Base::Distance(p1, p2); + float b = Base::Distance(p2, p0); + float c = Base::Distance(p0, p1); - // radius of the circle - float fRadius = Area(); - fRadius *= 2.0f/(a + b + c); + // radius of the circle + float fRadius = Area(); + fRadius *= 2.0f / (a + b + c); - // center of the circle - float w = a + b + c; - rclCenter.x = (a*p0.x + b*p1.x + c*p2.x)/w; - rclCenter.y = (a*p0.y + b*p1.y + c*p2.y)/w; - rclCenter.z = (a*p0.z + b*p1.z + c*p2.z)/w; + // center of the circle + float w = a + b + c; + rclCenter.x = (a * p0.x + b * p1.x + c * p2.x) / w; + rclCenter.y = (a * p0.y + b * p1.y + c * p2.y) / w; + rclCenter.z = (a * p0.z + b * p1.z + c * p2.z) / w; - return fRadius; + return fRadius; } float MeshGeomFacet::CenterOfCircumCircle(Base::Vector3f& rclCenter) const { - const Base::Vector3f& p0 = _aclPoints[0]; - const Base::Vector3f& p1 = _aclPoints[1]; - const Base::Vector3f& p2 = _aclPoints[2]; + const Base::Vector3f& p0 = _aclPoints[0]; + const Base::Vector3f& p1 = _aclPoints[1]; + const Base::Vector3f& p2 = _aclPoints[2]; - Base::Vector3f u = (p1-p0); - Base::Vector3f v = (p2-p1); - Base::Vector3f w = (p0-p2); + Base::Vector3f u = (p1 - p0); + Base::Vector3f v = (p2 - p1); + Base::Vector3f w = (p0 - p2); - double uu = (u * u); - double vv = (v * v); - double ww = (w * w); - double uv = - (u * v); - double vw = - (v * w); - double uw = - (w * u); + double uu = (u * u); + double vv = (v * v); + double ww = (w * w); + double uv = -(u * v); + double vw = -(v * w); + double uw = -(w * u); - double w0 = (2 * sqrt(uu * ww - uw * uw) * uw / (uu * ww)); - double w1 = (2 * sqrt(uu * vv - uv * uv) * uv / (uu * vv)); - double w2 = (2 * sqrt(vv * ww - vw * vw) * vw / (vv * ww)); + double w0 = (2 * sqrt(uu * ww - uw * uw) * uw / (uu * ww)); + double w1 = (2 * sqrt(uu * vv - uv * uv) * uv / (uu * vv)); + double w2 = (2 * sqrt(vv * ww - vw * vw) * vw / (vv * ww)); - // center of the circle - double wx = w0 + w1 + w2; - rclCenter.x = static_cast((w0*p0.x + w1*p1.x + w2*p2.x)/wx); - rclCenter.y = static_cast((w0*p0.y + w1*p1.y + w2*p2.y)/wx); - rclCenter.z = static_cast((w0*p0.z + w1*p1.z + w2*p2.z)/wx); + // center of the circle + double wx = w0 + w1 + w2; + rclCenter.x = static_cast((w0 * p0.x + w1 * p1.x + w2 * p2.x) / wx); + rclCenter.y = static_cast((w0 * p0.y + w1 * p1.y + w2 * p2.y) / wx); + rclCenter.z = static_cast((w0 * p0.z + w1 * p1.z + w2 * p2.z) / wx); - // radius of the circle - float fRadius = static_cast(sqrt(uu * vv * ww) / (4 * Area())); - return fRadius; + // radius of the circle + float fRadius = static_cast(sqrt(uu * vv * ww) / (4 * Area())); + return fRadius; } unsigned short MeshGeomFacet::NearestEdgeToPoint(const Base::Vector3f& rclPt) const { - unsigned short usSide; + unsigned short usSide; - const Base::Vector3f& rcP1 = _aclPoints[0]; - const Base::Vector3f& rcP2 = _aclPoints[1]; - const Base::Vector3f& rcP3 = _aclPoints[2]; + const Base::Vector3f& rcP1 = _aclPoints[0]; + const Base::Vector3f& rcP2 = _aclPoints[1]; + const Base::Vector3f& rcP3 = _aclPoints[2]; - float fD1 = FLOAT_MAX; - float fD2 = FLOAT_MAX; - float fD3 = FLOAT_MAX; + float fD1 = FLOAT_MAX; + float fD2 = FLOAT_MAX; + float fD3 = FLOAT_MAX; - // 1st edge - Base::Vector3f clDir = rcP2 - rcP1; - float fLen = Base::Distance(rcP2, rcP1); - float t = ( ( rclPt - rcP1 ) * clDir ) / ( fLen * fLen ); - if ( t < 0.0f ) - fD1 = Base::Distance(rclPt, rcP1); - else if ( t > 1.0f ) - fD1 = Base::Distance(rclPt, rcP2); - else - fD1 = ( ( ( rclPt - rcP1 ) % clDir).Length() ) / fLen; - - // 2nd edge - clDir = rcP3 - rcP2; - fLen = Base::Distance(rcP3, rcP2); - t = ( ( rclPt - rcP2 ) * clDir ) / ( fLen * fLen ); - if ( t < 0.0f ) - fD2 = Base::Distance(rclPt, rcP2); - else if ( t > 1.0f ) - fD2 = Base::Distance(rclPt, rcP3); - else - fD2 = ( ( ( rclPt - rcP2 ) % clDir).Length() ) / fLen; - - // 3rd edge - clDir = rcP1 - rcP3; - fLen = Base::Distance(rcP1, rcP3); - t = ( ( rclPt - rcP3 ) * clDir ) / ( fLen * fLen ); - if ( t < 0.0f ) - fD3 = Base::Distance(rclPt, rcP3); - else if ( t > 1.0f ) - fD3 = Base::Distance(rclPt, rcP1); - else - fD3 = ( ( ( rclPt - rcP3 ) % clDir).Length() ) / fLen; - - if ( fD1 < fD2 ) - { - if ( fD1 < fD3 ) - { - usSide = 0; + // 1st edge + Base::Vector3f clDir = rcP2 - rcP1; + float fLen = Base::Distance(rcP2, rcP1); + float t = ((rclPt - rcP1) * clDir) / (fLen * fLen); + if (t < 0.0f) { + fD1 = Base::Distance(rclPt, rcP1); } - else - { - usSide = 2; + else if (t > 1.0f) { + fD1 = Base::Distance(rclPt, rcP2); } - } - else - { - if ( fD2 < fD3 ) - { - usSide = 1; + else { + fD1 = (((rclPt - rcP1) % clDir).Length()) / fLen; } - else - { - usSide = 2; - } - } - return usSide; + // 2nd edge + clDir = rcP3 - rcP2; + fLen = Base::Distance(rcP3, rcP2); + t = ((rclPt - rcP2) * clDir) / (fLen * fLen); + if (t < 0.0f) { + fD2 = Base::Distance(rclPt, rcP2); + } + else if (t > 1.0f) { + fD2 = Base::Distance(rclPt, rcP3); + } + else { + fD2 = (((rclPt - rcP2) % clDir).Length()) / fLen; + } + + // 3rd edge + clDir = rcP1 - rcP3; + fLen = Base::Distance(rcP1, rcP3); + t = ((rclPt - rcP3) * clDir) / (fLen * fLen); + if (t < 0.0f) { + fD3 = Base::Distance(rclPt, rcP3); + } + else if (t > 1.0f) { + fD3 = Base::Distance(rclPt, rcP1); + } + else { + fD3 = (((rclPt - rcP3) % clDir).Length()) / fLen; + } + + if (fD1 < fD2) { + if (fD1 < fD3) { + usSide = 0; + } + else { + usSide = 2; + } + } + else { + if (fD2 < fD3) { + usSide = 1; + } + else { + usSide = 2; + } + } + + return usSide; } -void MeshGeomFacet::NearestEdgeToPoint(const Base::Vector3f& rclPt, float& fDistance, unsigned short& usSide) const +void MeshGeomFacet::NearestEdgeToPoint(const Base::Vector3f& rclPt, + float& fDistance, + unsigned short& usSide) const { - const Base::Vector3f& rcP1 = _aclPoints[0]; - const Base::Vector3f& rcP2 = _aclPoints[1]; - const Base::Vector3f& rcP3 = _aclPoints[2]; + const Base::Vector3f& rcP1 = _aclPoints[0]; + const Base::Vector3f& rcP2 = _aclPoints[1]; + const Base::Vector3f& rcP3 = _aclPoints[2]; - float fD1 = FLOAT_MAX; - float fD2 = FLOAT_MAX; - float fD3 = FLOAT_MAX; + float fD1 = FLOAT_MAX; + float fD2 = FLOAT_MAX; + float fD3 = FLOAT_MAX; - // 1st edge - Base::Vector3f clDir = rcP2 - rcP1; - float fLen = Base::Distance(rcP2, rcP1); - float t = ( ( rclPt - rcP1 ) * clDir ) / ( fLen * fLen ); - if ( t < 0.0f ) - fD1 = Base::Distance(rclPt, rcP1); - else if ( t > 1.0f ) - fD1 = Base::Distance(rclPt, rcP2); - else - fD1 = ( ( ( rclPt - rcP1 ) % clDir).Length() ) / fLen; - - // 2nd edge - clDir = rcP3 - rcP2; - fLen = Base::Distance(rcP3, rcP2); - t = ( ( rclPt - rcP2 ) * clDir ) / ( fLen * fLen ); - if ( t < 0.0f ) - fD2 = Base::Distance(rclPt, rcP2); - else if ( t > 1.0f ) - fD2 = Base::Distance(rclPt, rcP3); - else - fD2 = ( ( ( rclPt - rcP2 ) % clDir).Length() ) / fLen; - - // 3rd edge - clDir = rcP1 - rcP3; - fLen = Base::Distance(rcP1, rcP3); - t = ( ( rclPt - rcP3 ) * clDir ) / ( fLen * fLen ); - if ( t < 0.0f ) - fD3 = Base::Distance(rclPt, rcP3); - else if ( t > 1.0f ) - fD3 = Base::Distance(rclPt, rcP1); - else - fD3 = ( ( ( rclPt - rcP3 ) % clDir).Length() ) / fLen; - - if ( fD1 < fD2 ) - { - if ( fD1 < fD3 ) - { - usSide = 0; - fDistance = fD1; + // 1st edge + Base::Vector3f clDir = rcP2 - rcP1; + float fLen = Base::Distance(rcP2, rcP1); + float t = ((rclPt - rcP1) * clDir) / (fLen * fLen); + if (t < 0.0f) { + fD1 = Base::Distance(rclPt, rcP1); } - else - { - usSide = 2; - fDistance = fD3; + else if (t > 1.0f) { + fD1 = Base::Distance(rclPt, rcP2); } - } - else - { - if ( fD2 < fD3 ) - { - usSide = 1; - fDistance = fD2; + else { + fD1 = (((rclPt - rcP1) % clDir).Length()) / fLen; } - else - { - usSide = 2; - fDistance = fD3; + + // 2nd edge + clDir = rcP3 - rcP2; + fLen = Base::Distance(rcP3, rcP2); + t = ((rclPt - rcP2) * clDir) / (fLen * fLen); + if (t < 0.0f) { + fD2 = Base::Distance(rclPt, rcP2); + } + else if (t > 1.0f) { + fD2 = Base::Distance(rclPt, rcP3); + } + else { + fD2 = (((rclPt - rcP2) % clDir).Length()) / fLen; + } + + // 3rd edge + clDir = rcP1 - rcP3; + fLen = Base::Distance(rcP1, rcP3); + t = ((rclPt - rcP3) * clDir) / (fLen * fLen); + if (t < 0.0f) { + fD3 = Base::Distance(rclPt, rcP3); + } + else if (t > 1.0f) { + fD3 = Base::Distance(rclPt, rcP1); + } + else { + fD3 = (((rclPt - rcP3) % clDir).Length()) / fLen; + } + + if (fD1 < fD2) { + if (fD1 < fD3) { + usSide = 0; + fDistance = fD1; + } + else { + usSide = 2; + fDistance = fD3; + } + } + else { + if (fD2 < fD3) { + usSide = 1; + fDistance = fD2; + } + else { + usSide = 2; + fDistance = fD3; + } } - } } MeshGeomEdge MeshGeomFacet::GetEdge(short side) const { MeshGeomEdge edge; - edge._aclPoints[0] = this->_aclPoints[side %3]; - edge._aclPoints[1] = this->_aclPoints[(side+1)%3]; + edge._aclPoints[0] = this->_aclPoints[side % 3]; + edge._aclPoints[1] = this->_aclPoints[(side + 1) % 3]; return edge; } -float MeshGeomFacet::VolumeOfPrism (const MeshGeomFacet& rclF1) const +float MeshGeomFacet::VolumeOfPrism(const MeshGeomFacet& rclF1) const { - Base::Vector3f P1 = this->_aclPoints[0]; - Base::Vector3f P2 = this->_aclPoints[1]; - Base::Vector3f P3 = this->_aclPoints[2]; - Base::Vector3f Q1 = rclF1._aclPoints[0]; - Base::Vector3f Q2 = rclF1._aclPoints[1]; - Base::Vector3f Q3 = rclF1._aclPoints[2]; + Base::Vector3f P1 = this->_aclPoints[0]; + Base::Vector3f P2 = this->_aclPoints[1]; + Base::Vector3f P3 = this->_aclPoints[2]; + Base::Vector3f Q1 = rclF1._aclPoints[0]; + Base::Vector3f Q2 = rclF1._aclPoints[1]; + Base::Vector3f Q3 = rclF1._aclPoints[2]; - if ((P1-Q2).Length() < (P1-Q1).Length()) - { - Base::Vector3f tmp = Q1; - Q1 = Q2; - Q2 = tmp; - } - if ((P1-Q3).Length() < (P1-Q1).Length()) - { - Base::Vector3f tmp = Q1; - Q1 = Q3; - Q3 = tmp; - } - if ((P2-Q3).Length() < (P2-Q2).Length()) - { - Base::Vector3f tmp = Q2; - Q2 = Q3; - Q3 = tmp; - } + if ((P1 - Q2).Length() < (P1 - Q1).Length()) { + Base::Vector3f tmp = Q1; + Q1 = Q2; + Q2 = tmp; + } + if ((P1 - Q3).Length() < (P1 - Q1).Length()) { + Base::Vector3f tmp = Q1; + Q1 = Q3; + Q3 = tmp; + } + if ((P2 - Q3).Length() < (P2 - Q2).Length()) { + Base::Vector3f tmp = Q2; + Q2 = Q3; + Q3 = tmp; + } - Base::Vector3f N1 = (P2-P1) % (P3-P1); - Base::Vector3f N2 = (P2-P1) % (Q2-P1); - Base::Vector3f N3 = (Q2-P1) % (Q1-P1); + Base::Vector3f N1 = (P2 - P1) % (P3 - P1); + Base::Vector3f N2 = (P2 - P1) % (Q2 - P1); + Base::Vector3f N3 = (Q2 - P1) % (Q1 - P1); - float fVol=0.0f; - fVol += float(fabs((Q3-P1) * N1)); - fVol += float(fabs((Q3-P1) * N2)); - fVol += float(fabs((Q3-P1) * N3)); + float fVol = 0.0f; + fVol += float(fabs((Q3 - P1) * N1)); + fVol += float(fabs((Q3 - P1) * N2)); + fVol += float(fabs((Q3 - P1) * N3)); - fVol /= 6.0f; + fVol /= 6.0f; - return fVol;; + return fVol; + ; } -float MeshGeomFacet::MaximumAngle () const +float MeshGeomFacet::MaximumAngle() const { - float fMaxAngle = 0.0f; + float fMaxAngle = 0.0f; - for ( int i=0; i<3; i++ ) { - Base::Vector3f dir1(_aclPoints[(i+1)%3]-_aclPoints[i]); - Base::Vector3f dir2(_aclPoints[(i+2)%3]-_aclPoints[i]); - float fAngle = dir1.GetAngle(dir2); - if (fAngle > fMaxAngle) - fMaxAngle = fAngle; - } + for (int i = 0; i < 3; i++) { + Base::Vector3f dir1(_aclPoints[(i + 1) % 3] - _aclPoints[i]); + Base::Vector3f dir2(_aclPoints[(i + 2) % 3] - _aclPoints[i]); + float fAngle = dir1.GetAngle(dir2); + if (fAngle > fMaxAngle) { + fMaxAngle = fAngle; + } + } - return fMaxAngle; + return fMaxAngle; } -float MeshGeomFacet::MinimumAngle () const +float MeshGeomFacet::MinimumAngle() const { - float fMinAngle = Mathf::PI; + float fMinAngle = Mathf::PI; - for ( int i=0; i<3; i++ ) { - Base::Vector3f dir1(_aclPoints[(i+1)%3]-_aclPoints[i]); - Base::Vector3f dir2(_aclPoints[(i+2)%3]-_aclPoints[i]); - float fAngle = dir1.GetAngle(dir2); - if (fAngle < fMinAngle) - fMinAngle = fAngle; - } + for (int i = 0; i < 3; i++) { + Base::Vector3f dir1(_aclPoints[(i + 1) % 3] - _aclPoints[i]); + Base::Vector3f dir2(_aclPoints[(i + 2) % 3] - _aclPoints[i]); + float fAngle = dir1.GetAngle(dir2); + if (fAngle < fMinAngle) { + fMinAngle = fAngle; + } + } - return fMinAngle; + return fMinAngle; } bool MeshGeomFacet::IsPointOfSphere(const Base::Vector3f& rP) const { - float radius; - Base::Vector3f center; - radius = CenterOfCircumCircle(center); - radius *= radius; + float radius; + Base::Vector3f center; + radius = CenterOfCircumCircle(center); + radius *= radius; - float dist = Base::DistanceP2(rP, center); - return dist < radius; + float dist = Base::DistanceP2(rP, center); + return dist < radius; } bool MeshGeomFacet::IsPointOfSphere(const MeshGeomFacet& rFacet) const { - float radius; - Base::Vector3f center; - radius = CenterOfCircumCircle(center); - radius *= radius; + float radius; + Base::Vector3f center; + radius = CenterOfCircumCircle(center); + radius *= radius; - for (const auto& pnt : rFacet._aclPoints) { - float dist = Base::DistanceP2(pnt, center); - if (dist < radius) - return true; - } + for (const auto& pnt : rFacet._aclPoints) { + float dist = Base::DistanceP2(pnt, center); + if (dist < radius) { + return true; + } + } - return false; + return false; } float MeshGeomFacet::AspectRatio() const @@ -1501,16 +1576,18 @@ float MeshGeomFacet::AspectRatio() const Base::Vector3f d2 = _aclPoints[2] - _aclPoints[0]; float l2, maxl2 = d0.Sqr(); - if ((l2=d1.Sqr()) > maxl2) + if ((l2 = d1.Sqr()) > maxl2) { maxl2 = l2; + } d1 = d2; - if ((l2=d1.Sqr()) > maxl2) + if ((l2 = d1.Sqr()) > maxl2) { maxl2 = l2; + } // squared area of the parallelogram spanned by d0 and d1 float a2 = (d0 % d1).Sqr(); - return float(sqrt( (maxl2 * maxl2) / a2 )); + return float(sqrt((maxl2 * maxl2) / a2)); } float MeshGeomFacet::AspectRatio2() const diff --git a/src/Mod/Mesh/App/Core/Elements.h b/src/Mod/Mesh/App/Core/Elements.h index cf2a073715..dfd349a81b 100644 --- a/src/Mod/Mesh/App/Core/Elements.h +++ b/src/Mod/Mesh/App/Core/Elements.h @@ -39,7 +39,8 @@ using Base::Vector3f; #endif -namespace MeshCore { +namespace MeshCore +{ class MeshHelpEdge; class MeshPoint; @@ -52,8 +53,8 @@ class MeshPoint; class MeshExport MeshHelpEdge { public: - inline bool operator == (const MeshHelpEdge &rclEdge) const; - PointIndex _ulIndex[2]; // point indices + inline bool operator==(const MeshHelpEdge& rclEdge) const; + PointIndex _ulIndex[2]; // point indices }; /** @@ -63,8 +64,8 @@ public: class MeshExport MeshIndexEdge { public: - FacetIndex _ulFacetIndex; // Facet index - unsigned short _ausCorner[2]; // corner point indices of the facet + FacetIndex _ulFacetIndex; // Facet index + unsigned short _ausCorner[2]; // corner point indices of the facet }; /** MeshEdge just a pair of two point indices */ @@ -72,19 +73,19 @@ using MeshEdge = std::pair; struct MeshExport EdgeCollapse { - PointIndex _fromPoint; - PointIndex _toPoint; - std::vector _adjacentFrom; // adjacent points to _fromPoint - std::vector _adjacentTo; // adjacent points to _toPoint - std::vector _removeFacets; - std::vector _changeFacets; + PointIndex _fromPoint; + PointIndex _toPoint; + std::vector _adjacentFrom; // adjacent points to _fromPoint + std::vector _adjacentTo; // adjacent points to _toPoint + std::vector _removeFacets; + std::vector _changeFacets; }; struct MeshExport VertexCollapse { - PointIndex _point; - std::vector _circumPoints; - std::vector _circumFacets; + PointIndex _point; + std::vector _circumPoints; + std::vector _circumFacets; }; /** @@ -103,51 +104,78 @@ struct MeshExport VertexCollapse class MeshExport MeshPoint: public Base::Vector3f { public: - enum TFlagType {INVALID=1, VISIT=2, SEGMENT=4, MARKED=8, SELECTED=16, REV=32, TMP0=64, TMP1=128}; + enum TFlagType + { + INVALID = 1, + VISIT = 2, + SEGMENT = 4, + MARKED = 8, + SELECTED = 16, + REV = 32, + TMP0 = 64, + TMP1 = 128 + }; - /** @name Construction */ - //@{ - MeshPoint () : _ucFlag(0), _ulProp(0) { } - inline MeshPoint (float x, float y, float z); - inline MeshPoint (const Base::Vector3f &rclPt);//explicit bombs - inline MeshPoint (const MeshPoint &rclPt) = default; - inline MeshPoint (MeshPoint &&rclPt) = default; - ~MeshPoint () = default; - //@} + /** @name Construction */ + //@{ + MeshPoint() + : _ucFlag(0) + , _ulProp(0) + {} + inline MeshPoint(float x, float y, float z); + inline MeshPoint(const Base::Vector3f& rclPt); // explicit bombs + inline MeshPoint(const MeshPoint& rclPt) = default; + inline MeshPoint(MeshPoint&& rclPt) = default; + ~MeshPoint() = default; + //@} public: - /** @name Flag state - * @note All flag methods are const as they do NOT change the actual behaviour of the object - */ - //@{ - void SetFlag (TFlagType tF) const - { _ucFlag |= static_cast(tF); } - void ResetFlag (TFlagType tF) const - { _ucFlag &= ~static_cast(tF); } - bool IsFlag (TFlagType tF) const - { return (_ucFlag & static_cast(tF)) == static_cast(tF); } - void ResetInvalid () const - { ResetFlag(INVALID); } - void SetInvalid () const - { SetFlag(INVALID); } - bool IsValid () const - { return !IsFlag(INVALID); } - void SetProperty(unsigned long uP) const - { _ulProp = uP; } - //@} + /** @name Flag state + * @note All flag methods are const as they do NOT change the actual behaviour of the object + */ + //@{ + void SetFlag(TFlagType tF) const + { + _ucFlag |= static_cast(tF); + } + void ResetFlag(TFlagType tF) const + { + _ucFlag &= ~static_cast(tF); + } + bool IsFlag(TFlagType tF) const + { + return (_ucFlag & static_cast(tF)) == static_cast(tF); + } + void ResetInvalid() const + { + ResetFlag(INVALID); + } + void SetInvalid() const + { + SetFlag(INVALID); + } + bool IsValid() const + { + return !IsFlag(INVALID); + } + void SetProperty(unsigned long uP) const + { + _ulProp = uP; + } + //@} - // Assignment - inline MeshPoint& operator = (const MeshPoint &rclPt) = default; - inline MeshPoint& operator = (MeshPoint &&rclPt) = default; + // Assignment + inline MeshPoint& operator=(const MeshPoint& rclPt) = default; + inline MeshPoint& operator=(MeshPoint&& rclPt) = default; - // compare operator - inline bool operator == (const MeshPoint &rclPt) const; - inline bool operator == (const Base::Vector3f &rclV) const; - inline bool operator < (const MeshPoint &rclPt) const; + // compare operator + inline bool operator==(const MeshPoint& rclPt) const; + inline bool operator==(const Base::Vector3f& rclV) const; + inline bool operator<(const MeshPoint& rclPt) const; public: - mutable unsigned char _ucFlag; /**< Flag member */ - mutable unsigned long _ulProp; /**< Free usable property */ + mutable unsigned char _ucFlag; /**< Flag member */ + mutable unsigned long _ulProp; /**< Free usable property */ }; /** @@ -157,62 +185,70 @@ public: class MeshExport MeshGeomEdge { public: - MeshGeomEdge () = default; + MeshGeomEdge() = default; - /** Checks if the edge is inside the bounding box or intersects with it. */ - bool ContainedByOrIntersectBoundingBox (const Base::BoundBox3f &rclBB ) const; - /** Returns the bounding box of the edge. */ - Base::BoundBox3f GetBoundBox () const; - /** Checks if the edge intersects with the given bounding box. */ - bool IntersectBoundingBox (const Base::BoundBox3f &rclBB) const; - /** Calculates the intersection point of the line defined by the base \a rclPt and the direction \a rclDir - * with the edge. The intersection must be inside the edge. If there is no intersection false is returned. - */ - bool IntersectWithLine (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, Base::Vector3f &rclRes) const; - /** Calculates the intersection point of an edge with this edge. - * The intersection must be inside both edges. If there is no intersection false is returned. - */ - bool IntersectWithEdge (const MeshGeomEdge &edge, Base::Vector3f &res) const; - /** Calculates the intersection point of the plane defined by the base \a rclPt and the direction \a rclDir - * with the edge. The intersection must be inside the edge. If there is no intersection false is returned. - */ - bool IntersectWithPlane (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, Base::Vector3f &rclRes) const; - /** - * Calculates the projection of a point onto the line defined by the edge. The caller must check if - * the projection point is inside the edge. - */ - void ProjectPointToLine (const Base::Vector3f &rclPoint, Base::Vector3f &rclProj) const; - /** - * Get the closest points \a rclPnt1 and \a rclPnt2 of the line defined by this edge and the line - * defined by \a rclPt and \a rclDir. - * If the two points are identical then both lines intersect each other. - */ - void ClosestPointsToLine(const Base::Vector3f &linePt, const Base::Vector3f &lineDir, - Base::Vector3f& rclPnt1, Base::Vector3f& rclPnt2) const; - /** - * Checks if the point is part of the edge. A point is regarded as part - * of an edge if the distance is lower than \a fDistance to the projected point - * of \a rclPoint on the edge. - */ - bool IsPointOf (const Base::Vector3f &rclPoint, float fDistance) const; - /** - * Checks if the projection point of \a point lies on the edge. - */ - bool IsProjectionPointOf(const Base::Vector3f& point) const; - /** - * Checks if the two edges are parallel. - * \note Parallel edges could be collinear. - */ - bool IsParallel(const MeshGeomEdge &edge) const; - /** - * Checks if the two edges are collinear. - * \note Collinear edges always are parallel. - */ - bool IsCollinear(const MeshGeomEdge &edge) const; + /** Checks if the edge is inside the bounding box or intersects with it. */ + bool ContainedByOrIntersectBoundingBox(const Base::BoundBox3f& rclBB) const; + /** Returns the bounding box of the edge. */ + Base::BoundBox3f GetBoundBox() const; + /** Checks if the edge intersects with the given bounding box. */ + bool IntersectBoundingBox(const Base::BoundBox3f& rclBB) const; + /** Calculates the intersection point of the line defined by the base \a rclPt and the direction + * \a rclDir with the edge. The intersection must be inside the edge. If there is no + * intersection false is returned. + */ + bool IntersectWithLine(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + Base::Vector3f& rclRes) const; + /** Calculates the intersection point of an edge with this edge. + * The intersection must be inside both edges. If there is no intersection false is returned. + */ + bool IntersectWithEdge(const MeshGeomEdge& edge, Base::Vector3f& res) const; + /** Calculates the intersection point of the plane defined by the base \a rclPt and the + * direction \a rclDir with the edge. The intersection must be inside the edge. If there is no + * intersection false is returned. + */ + bool IntersectWithPlane(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + Base::Vector3f& rclRes) const; + /** + * Calculates the projection of a point onto the line defined by the edge. The caller must check + * if the projection point is inside the edge. + */ + void ProjectPointToLine(const Base::Vector3f& rclPoint, Base::Vector3f& rclProj) const; + /** + * Get the closest points \a rclPnt1 and \a rclPnt2 of the line defined by this edge and the + * line defined by \a rclPt and \a rclDir. If the two points are identical then both lines + * intersect each other. + */ + void ClosestPointsToLine(const Base::Vector3f& linePt, + const Base::Vector3f& lineDir, + Base::Vector3f& rclPnt1, + Base::Vector3f& rclPnt2) const; + /** + * Checks if the point is part of the edge. A point is regarded as part + * of an edge if the distance is lower than \a fDistance to the projected point + * of \a rclPoint on the edge. + */ + bool IsPointOf(const Base::Vector3f& rclPoint, float fDistance) const; + /** + * Checks if the projection point of \a point lies on the edge. + */ + bool IsProjectionPointOf(const Base::Vector3f& point) const; + /** + * Checks if the two edges are parallel. + * \note Parallel edges could be collinear. + */ + bool IsParallel(const MeshGeomEdge& edge) const; + /** + * Checks if the two edges are collinear. + * \note Collinear edges always are parallel. + */ + bool IsCollinear(const MeshGeomEdge& edge) const; public: - Base::Vector3f _aclPoints[2]; /**< Corner points */ - bool _bBorder{false}; /**< Set to true if border edge */ + Base::Vector3f _aclPoints[2]; /**< Corner points */ + bool _bBorder {false}; /**< Set to true if border edge */ }; /** @@ -235,130 +271,162 @@ public: class MeshFacet { public: - enum TFlagType {INVALID=1, VISIT=2, SEGMENT=4, MARKED=8, SELECTED=16, REV=32, TMP0=64, TMP1=128}; + enum TFlagType + { + INVALID = 1, + VISIT = 2, + SEGMENT = 4, + MARKED = 8, + SELECTED = 16, + REV = 32, + TMP0 = 64, + TMP1 = 128 + }; public: - /** @name Construction */ - //@{ - inline MeshFacet (); - inline MeshFacet(const MeshFacet &rclF) = default; - inline MeshFacet(MeshFacet &&rclF) = default; - inline MeshFacet(PointIndex p1,PointIndex p2,PointIndex p3,FacetIndex n1=FACET_INDEX_MAX,FacetIndex n2=FACET_INDEX_MAX,FacetIndex n3=FACET_INDEX_MAX); - ~MeshFacet () = default; - //@} + /** @name Construction */ + //@{ + inline MeshFacet(); + inline MeshFacet(const MeshFacet& rclF) = default; + inline MeshFacet(MeshFacet&& rclF) = default; + inline MeshFacet(PointIndex p1, + PointIndex p2, + PointIndex p3, + FacetIndex n1 = FACET_INDEX_MAX, + FacetIndex n2 = FACET_INDEX_MAX, + FacetIndex n3 = FACET_INDEX_MAX); + ~MeshFacet() = default; + //@} - /** @name Flag state - * @note All flag methods are const as they do NOT change the actual behaviour of the object - */ - //@{ - void SetFlag (TFlagType tF) const - { _ucFlag |= static_cast(tF); } - void ResetFlag (TFlagType tF) const - { _ucFlag &= ~static_cast(tF); } - bool IsFlag (TFlagType tF) const - { return (_ucFlag & static_cast(tF)) == static_cast(tF); } - void ResetInvalid () const - { ResetFlag(INVALID); } - void SetProperty(unsigned long uP) const - { _ulProp = uP; } - /** - * Marks a facet as invalid. Should be used only temporary from within an algorithm - * (e.g. deletion of several facets) but must not be set permanently. - * From outside the data-structure must not have invalid facets. - */ - void SetInvalid () const - { SetFlag(INVALID); } - bool IsValid () const - { return !IsFlag(INVALID); } - //@} + /** @name Flag state + * @note All flag methods are const as they do NOT change the actual behaviour of the object + */ + //@{ + void SetFlag(TFlagType tF) const + { + _ucFlag |= static_cast(tF); + } + void ResetFlag(TFlagType tF) const + { + _ucFlag &= ~static_cast(tF); + } + bool IsFlag(TFlagType tF) const + { + return (_ucFlag & static_cast(tF)) == static_cast(tF); + } + void ResetInvalid() const + { + ResetFlag(INVALID); + } + void SetProperty(unsigned long uP) const + { + _ulProp = uP; + } + /** + * Marks a facet as invalid. Should be used only temporary from within an algorithm + * (e.g. deletion of several facets) but must not be set permanently. + * From outside the data-structure must not have invalid facets. + */ + void SetInvalid() const + { + SetFlag(INVALID); + } + bool IsValid() const + { + return !IsFlag(INVALID); + } + //@} - // Assignment - inline MeshFacet& operator = (const MeshFacet &rclF) = default; - inline MeshFacet& operator = (MeshFacet &&rclF) = default; - inline void SetVertices(PointIndex,PointIndex,PointIndex); - inline void SetNeighbours(FacetIndex,FacetIndex,FacetIndex); + // Assignment + inline MeshFacet& operator=(const MeshFacet& rclF) = default; + inline MeshFacet& operator=(MeshFacet&& rclF) = default; + inline void SetVertices(PointIndex, PointIndex, PointIndex); + inline void SetNeighbours(FacetIndex, FacetIndex, FacetIndex); - /** - * Returns the indices of the corner points of the given edge number. - */ - inline void GetEdge (unsigned short usSide, MeshHelpEdge &rclEdge) const; - /** - * Returns the indices of the corner points of the given edge number. - */ - inline std::pair GetEdge (unsigned short usSide) const; - /** - * Returns the edge-number to the given index of neighbour facet. - * If \a ulNIndex is not a neighbour USHRT_MAX is returned. - */ - inline unsigned short Side (FacetIndex ulNIndex) const; - /** - * Returns the edge-number defined by two points. If one point is - * not a corner point USHRT_MAX is returned. - */ - inline unsigned short Side (PointIndex ulP0, PointIndex P1) const; - /** - * Returns the edge-number defined by the shared edge of both facets. If the facets don't - * share a common edge USHRT_MAX is returned. - */ - inline unsigned short Side (const MeshFacet& rcFace) const; - /** - * Returns true if this facet shares the same three points as \a rcFace. - * The orientation is not of interest in this case. - */ - inline bool IsEqual (const MeshFacet& rcFace) const; - /** - * Replaces the index of the corner point that is equal to \a ulOrig - * by \a ulNew. If the facet does not have a corner point with this index - * nothing happens. - */ - inline void Transpose (PointIndex ulOrig, PointIndex ulNew); - /** - * Decrement the index for each corner point that is higher than \a ulIndex. - */ - inline void Decrement (PointIndex ulIndex); - /** - * Checks if the facets references the given point index. - */ - inline bool HasPoint(PointIndex) const; - /** - * Replaces the index of the neighbour facet that is equal to \a ulOrig - * by \a ulNew. If the facet does not have a neighbourt with this index - * nothing happens. - */ - inline void ReplaceNeighbour (FacetIndex ulOrig, FacetIndex ulNew); - /** - * Checks if the neighbour exists at the given edge-number. - */ - bool HasNeighbour (unsigned short usSide) const - { return (_aulNeighbours[usSide] != FACET_INDEX_MAX); } - /** - * Checks if the given index is a neighbour facet. - */ - bool IsNeighbour(FacetIndex index) const { - return Side(index) < 3; - } - /** Counts the number of edges without neighbour. */ - inline unsigned short CountOpenEdges() const; - /** Returns true if there is an edge without neighbour, otherwise false. */ - inline bool HasOpenEdge() const; - /** Returns true if the two facets have the same orientation, false otherwise - * Therefore the two facets must be adjacent. - */ - inline bool HasSameOrientation(const MeshFacet&) const; - /** Checks whether the facet is degenerated to a line of point. */ - inline bool IsDegenerated() const; - /** Flips the orientation of the facet. */ - void FlipNormal () - { - std::swap(_aulPoints[1], _aulPoints[2]); - std::swap(_aulNeighbours[0], _aulNeighbours[2]); - } + /** + * Returns the indices of the corner points of the given edge number. + */ + inline void GetEdge(unsigned short usSide, MeshHelpEdge& rclEdge) const; + /** + * Returns the indices of the corner points of the given edge number. + */ + inline std::pair GetEdge(unsigned short usSide) const; + /** + * Returns the edge-number to the given index of neighbour facet. + * If \a ulNIndex is not a neighbour USHRT_MAX is returned. + */ + inline unsigned short Side(FacetIndex ulNIndex) const; + /** + * Returns the edge-number defined by two points. If one point is + * not a corner point USHRT_MAX is returned. + */ + inline unsigned short Side(PointIndex ulP0, PointIndex P1) const; + /** + * Returns the edge-number defined by the shared edge of both facets. If the facets don't + * share a common edge USHRT_MAX is returned. + */ + inline unsigned short Side(const MeshFacet& rcFace) const; + /** + * Returns true if this facet shares the same three points as \a rcFace. + * The orientation is not of interest in this case. + */ + inline bool IsEqual(const MeshFacet& rcFace) const; + /** + * Replaces the index of the corner point that is equal to \a ulOrig + * by \a ulNew. If the facet does not have a corner point with this index + * nothing happens. + */ + inline void Transpose(PointIndex ulOrig, PointIndex ulNew); + /** + * Decrement the index for each corner point that is higher than \a ulIndex. + */ + inline void Decrement(PointIndex ulIndex); + /** + * Checks if the facets references the given point index. + */ + inline bool HasPoint(PointIndex) const; + /** + * Replaces the index of the neighbour facet that is equal to \a ulOrig + * by \a ulNew. If the facet does not have a neighbourt with this index + * nothing happens. + */ + inline void ReplaceNeighbour(FacetIndex ulOrig, FacetIndex ulNew); + /** + * Checks if the neighbour exists at the given edge-number. + */ + bool HasNeighbour(unsigned short usSide) const + { + return (_aulNeighbours[usSide] != FACET_INDEX_MAX); + } + /** + * Checks if the given index is a neighbour facet. + */ + bool IsNeighbour(FacetIndex index) const + { + return Side(index) < 3; + } + /** Counts the number of edges without neighbour. */ + inline unsigned short CountOpenEdges() const; + /** Returns true if there is an edge without neighbour, otherwise false. */ + inline bool HasOpenEdge() const; + /** Returns true if the two facets have the same orientation, false otherwise + * Therefore the two facets must be adjacent. + */ + inline bool HasSameOrientation(const MeshFacet&) const; + /** Checks whether the facet is degenerated to a line of point. */ + inline bool IsDegenerated() const; + /** Flips the orientation of the facet. */ + void FlipNormal() + { + std::swap(_aulPoints[1], _aulPoints[2]); + std::swap(_aulNeighbours[0], _aulNeighbours[2]); + } public: - mutable unsigned char _ucFlag; /**< Flag member. */ - mutable unsigned long _ulProp; /**< Free usable property. */ - PointIndex _aulPoints[3]; /**< Indices of corner points. */ - FacetIndex _aulNeighbours[3]; /**< Indices of neighbour facets. */ + mutable unsigned char _ucFlag; /**< Flag member. */ + mutable unsigned long _ulProp; /**< Free usable property. */ + PointIndex _aulPoints[3]; /**< Indices of corner points. */ + FacetIndex _aulNeighbours[3]; /**< Indices of neighbour facets. */ }; /** @@ -368,211 +436,243 @@ public: class MeshExport MeshGeomFacet { public: - /** @name Construction */ - //@{ - /// default constructor - MeshGeomFacet (); - /// Constructor with the corner points - MeshGeomFacet (const Base::Vector3f &v1,const Base::Vector3f &v2,const Base::Vector3f &v3); - MeshGeomFacet(const MeshGeomFacet&) = default; - MeshGeomFacet(MeshGeomFacet&&) = default; - /// Destruction - ~MeshGeomFacet () = default; - //@} + /** @name Construction */ + //@{ + /// default constructor + MeshGeomFacet(); + /// Constructor with the corner points + MeshGeomFacet(const Base::Vector3f& v1, const Base::Vector3f& v2, const Base::Vector3f& v3); + MeshGeomFacet(const MeshGeomFacet&) = default; + MeshGeomFacet(MeshGeomFacet&&) = default; + /// Destruction + ~MeshGeomFacet() = default; + //@} - MeshGeomFacet& operator = (const MeshGeomFacet&) = default; - MeshGeomFacet& operator = (MeshGeomFacet&&) = default; + MeshGeomFacet& operator=(const MeshGeomFacet&) = default; + MeshGeomFacet& operator=(MeshGeomFacet&&) = default; public: - /** - * Checks if the point is part of the facet. A point is regarded as part - * of a facet if the distance is lower \a fDistance and the projected point - * in the facet normal direction is inside the triangle. - */ - bool IsPointOf (const Base::Vector3f &rclPoint, float fDistance) const; - /** - * Checks if the point is inside or at the border of the facet. The point - * must already exactly lie on the plane defined by the facet, which is not - * checked. This method is very efficient. - */ - bool IsPointOf (const Base::Vector3f &rclPoint) const; - /** Checks whether the given point is inside the facet with tolerance \a fDistance. - * This method does actually the same as IsPointOf() but this implementation - * is done more effective through comparison of normals. - */ - bool IsPointOfFace (const Base::Vector3f& rclP, float fDistance) const; - /** Calculates the weights \a w1, ..., \a w3 of the corners to get the point \a rclP, i.e. - * rclP = w0*v0 + w1*v1 + w2*v2 (v0-v2 are the corners corners). - * If w0+w1+w2==1.0 then the point rclP lies on the plane that is spanned by the facet, otherwise - * the point doesn't lie on the plane. - * If the sum of wi is 1 and if each wi is between [0,1] than the point lies inside - * the facet or on the border, respectively. - * - * If the point doesn't lie on the plane false is returned, true otherwise. - */ - bool Weights(const Base::Vector3f& rclP, float& w0, float& w1, float& w2) const; - /** - * Calculates the distance of a point to the plane defined by the triangle. - */ - inline float DistancePlaneToPoint (const Base::Vector3f &rclPoint) const; - /** - * Calculates the projection of a point onto the plane defined by the triangle. - */ - void ProjectPointToPlane (const Base::Vector3f &rclPoint, Base::Vector3f &rclProj) const; - /** - * Calculates the projection of a facet onto the plane defined by the triangle. - */ - void ProjectFacetToPlane (MeshGeomFacet &rclFacet) const; - /** - * Checks whether the triangle is degenerated. A triangle is degenerated if its area - * is less than an epsilon. - */ - bool IsDegenerated(float epsilon) const; - /** - * Checks whether the triangle is deformed. A triangle is deformed if an angle - * exceeds a given maximum angle or falls below a given minimum angle. - * For performance reasons the cosine of minimum and maximum angle is expected. - */ - bool IsDeformed(float fCosOfMinAngle, float fCosOfMaxAngle) const; - /** - * Enlarges the triangle. - */ - void Enlarge (float fDist); - /** - * Calculates the facet normal for storing internally. - */ - inline void CalcNormal () const; - /** - * Arrange the facet normal so the both vectors have the same orientation. - */ - inline void ArrangeNormal (const Base::Vector3f &rclN); - /** - * Adjusts the facet's orientation to its normal. - */ - inline void AdjustCirculationDirection (); - /** Invalidate the normal. It will be recomputed when querying it. */ - void NormalInvalid () { _bNormalCalculated = false; } - /** Query the flag state of the facet. */ - bool IsFlag (MeshFacet::TFlagType tF) const - { return (_ucFlag & static_cast(tF)) == static_cast(tF); } + /** + * Checks if the point is part of the facet. A point is regarded as part + * of a facet if the distance is lower \a fDistance and the projected point + * in the facet normal direction is inside the triangle. + */ + bool IsPointOf(const Base::Vector3f& rclPoint, float fDistance) const; + /** + * Checks if the point is inside or at the border of the facet. The point + * must already exactly lie on the plane defined by the facet, which is not + * checked. This method is very efficient. + */ + bool IsPointOf(const Base::Vector3f& rclPoint) const; + /** Checks whether the given point is inside the facet with tolerance \a fDistance. + * This method does actually the same as IsPointOf() but this implementation + * is done more effective through comparison of normals. + */ + bool IsPointOfFace(const Base::Vector3f& rclP, float fDistance) const; + /** Calculates the weights \a w1, ..., \a w3 of the corners to get the point \a rclP, i.e. + * rclP = w0*v0 + w1*v1 + w2*v2 (v0-v2 are the corners corners). + * If w0+w1+w2==1.0 then the point rclP lies on the plane that is spanned by the facet, + * otherwise the point doesn't lie on the plane. If the sum of wi is 1 and if each wi is between + * [0,1] than the point lies inside the facet or on the border, respectively. + * + * If the point doesn't lie on the plane false is returned, true otherwise. + */ + bool Weights(const Base::Vector3f& rclP, float& w0, float& w1, float& w2) const; + /** + * Calculates the distance of a point to the plane defined by the triangle. + */ + inline float DistancePlaneToPoint(const Base::Vector3f& rclPoint) const; + /** + * Calculates the projection of a point onto the plane defined by the triangle. + */ + void ProjectPointToPlane(const Base::Vector3f& rclPoint, Base::Vector3f& rclProj) const; + /** + * Calculates the projection of a facet onto the plane defined by the triangle. + */ + void ProjectFacetToPlane(MeshGeomFacet& rclFacet) const; + /** + * Checks whether the triangle is degenerated. A triangle is degenerated if its area + * is less than an epsilon. + */ + bool IsDegenerated(float epsilon) const; + /** + * Checks whether the triangle is deformed. A triangle is deformed if an angle + * exceeds a given maximum angle or falls below a given minimum angle. + * For performance reasons the cosine of minimum and maximum angle is expected. + */ + bool IsDeformed(float fCosOfMinAngle, float fCosOfMaxAngle) const; + /** + * Enlarges the triangle. + */ + void Enlarge(float fDist); + /** + * Calculates the facet normal for storing internally. + */ + inline void CalcNormal() const; + /** + * Arrange the facet normal so the both vectors have the same orientation. + */ + inline void ArrangeNormal(const Base::Vector3f& rclN); + /** + * Adjusts the facet's orientation to its normal. + */ + inline void AdjustCirculationDirection(); + /** Invalidate the normal. It will be recomputed when querying it. */ + void NormalInvalid() + { + _bNormalCalculated = false; + } + /** Query the flag state of the facet. */ + bool IsFlag(MeshFacet::TFlagType tF) const + { + return (_ucFlag & static_cast(tF)) == static_cast(tF); + } /** Set flag state */ - void SetFlag (MeshFacet::TFlagType tF) - { _ucFlag |= static_cast(tF); } - /** Reset flag state */ - void ResetFlag (MeshFacet::TFlagType tF) - { _ucFlag &= ~static_cast(tF); } - /** Calculates the facet's gravity point. */ - inline Base::Vector3f GetGravityPoint () const; - /** Returns the normal of the facet. */ - inline Base::Vector3f GetNormal () const; - /** Sets the facet's normal. */ - inline void SetNormal (const Base::Vector3f &rclNormal); - /** Returns the wrapping bounding box. */ - inline Base::BoundBox3f GetBoundBox () const; - /** Calculates the perimeter of the facet. */ - inline float Perimeter() const; - /** Calculates the area of a facet. */ - inline float Area () const; - /** Calculates the maximum angle of a facet. */ - float MaximumAngle () const; - /** Calculates the minimum angle of a facet. */ - float MinimumAngle () const; - /** Checks if the facet is inside the bounding box or intersects with it. */ - inline bool ContainedByOrIntersectBoundingBox (const Base::BoundBox3f &rcBB) const; - /** Checks if the facet intersects with the given bounding box. */ - bool IntersectBoundingBox ( const Base::BoundBox3f &rclBB ) const; - /** This method checks if both facets intersect. - */ - bool IntersectWithFacet(const MeshGeomFacet &rclFacet) const; - /** - * Intersect the facet with the other facet - * The result is line given by two points (if intersected). - * Return is the number of intersections points: 0: no intersection, 1: one intersection point (rclPt0), 2: two intersections points (rclPt0, rclPt1) - */ - int IntersectWithFacet (const MeshGeomFacet& facet, Base::Vector3f& rclPt0, Base::Vector3f& rclPt1) const; - /** Calculates the shortest distance from the line segment defined by \a rcP1 and \a rcP2 to - * this facet. - */ - float DistanceToLineSegment (const Base::Vector3f &rcP1, const Base::Vector3f &rcP2) const; - /** Calculates the shortest distance from the point \a rcPt to the facet. */ - float DistanceToPoint (const Base::Vector3f &rcPt) const - { Base::Vector3f res; return DistanceToPoint(rcPt, res); } - /** Calculates the shortest distance from the point \a rcPt to the facet. \a rclNt is the point of the facet - * with shortest distance. - */ - float DistanceToPoint ( const Base::Vector3f &rclPt, Base::Vector3f& rclNt ) const; - /** Calculates the intersection point of the line defined by the base \a rclPt and the direction \a rclDir - * with the facet. The intersection must be inside the facet. If there is no intersection false is returned. - */ - bool IntersectWithLine (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, Base::Vector3f &rclRes) const; - /** Calculates the intersection point of the line defined by the base \a rclPt and the direction \a rclDir - * with the facet. The intersection must be inside the facet. If there is no intersection false is returned. - * This does actually the same as IntersectWithLine() with one additionally constraint that the angle - * between the direction of the line and the normal of the plane must not exceed \a fMaxAngle. - */ - bool Foraminate (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, Base::Vector3f &rclRes, float fMaxAngle = Mathf::PI) const; - /** Checks if the facet intersects with the plane defined by the base \a rclBase and the normal - * \a rclNormal and returns true if two points are found, false otherwise. - */ - bool IntersectWithPlane (const Base::Vector3f &rclBase, const Base::Vector3f &rclNormal, Base::Vector3f &rclP1, Base::Vector3f &rclP2) const; - /** - * Checks if the facet intersects with the plane defined by the base \a rclBase and the normal - * \a rclNormal. - */ - inline bool IntersectWithPlane (const Base::Vector3f &rclBase, const Base::Vector3f &rclNormal) const; - /** Checks if the plane defined by the facet \a rclFacet intersects with the line defined by the base - * \a rclBase and the direction \a rclNormal and returns the intersection point \a rclRes if possible. - */ - bool IntersectPlaneWithLine (const Base::Vector3f &rclBase, const Base::Vector3f &rclNormal, Base::Vector3f &rclRes ) const; - /** Calculates the volume of the prism defined by two facets. - * \note The two facets must not intersect. - */ - float VolumeOfPrism (const MeshGeomFacet& rclF) const; - /** Subsamples the facet into points with resolution \a fStep. */ - void SubSample (float fStep, std::vector &rclPoints) const; - /** Calculates the center and radius of the inscribed circle of the facet. */ - float CenterOfInscribedCircle(Base::Vector3f& rclCenter) const; - /** Calculates the center and radius of the circum circle of the facet. */ - float CenterOfCircumCircle(Base::Vector3f& rclCenter) const; - /** Returns the edge number of the facet that is nearest to the point \a rclPt. */ - unsigned short NearestEdgeToPoint(const Base::Vector3f& rclPt) const; - /** Returns the edge number \a side of the facet and the distance to the edge that is nearest to the point \a rclPt. */ - void NearestEdgeToPoint(const Base::Vector3f& rclPt, float& fDistance, unsigned short& side) const; - /** Returns the edge for \a side. */ - MeshGeomEdge GetEdge(short side) const; - /** The center and radius of the circum circle define a sphere in 3D. If the point \a rP is part of this sphere true is - * returned, otherwise false. - */ - bool IsPointOfSphere(const Base::Vector3f& rP) const; - /** This is an overloaded member function, provided for convenience. It behaves essentially like the above function. - * If one of the facet's points is inside the sphere true is returned, otherwise false. - */ - bool IsPointOfSphere(const MeshGeomFacet& rFacet) const; - /** The aspect ratio is the longest edge length divided by its height. - */ - float AspectRatio() const; - /** The alternative aspect ration is the ratio of the radius of the circum-circle and twice the radius of the in-circle. - */ - float AspectRatio2() const; - /** The roundness is in the range between 0.0 (colinear) and 1.0 (equilateral). - */ - float Roundness() const; - /** Apply a transformation on the triangle. - */ - void Transform(const Base::Matrix4D&); - /** - * Checks if the two triangles are coplanar. - */ - bool IsCoplanar(const MeshGeomFacet &facet) const; + void SetFlag(MeshFacet::TFlagType tF) + { + _ucFlag |= static_cast(tF); + } + /** Reset flag state */ + void ResetFlag(MeshFacet::TFlagType tF) + { + _ucFlag &= ~static_cast(tF); + } + /** Calculates the facet's gravity point. */ + inline Base::Vector3f GetGravityPoint() const; + /** Returns the normal of the facet. */ + inline Base::Vector3f GetNormal() const; + /** Sets the facet's normal. */ + inline void SetNormal(const Base::Vector3f& rclNormal); + /** Returns the wrapping bounding box. */ + inline Base::BoundBox3f GetBoundBox() const; + /** Calculates the perimeter of the facet. */ + inline float Perimeter() const; + /** Calculates the area of a facet. */ + inline float Area() const; + /** Calculates the maximum angle of a facet. */ + float MaximumAngle() const; + /** Calculates the minimum angle of a facet. */ + float MinimumAngle() const; + /** Checks if the facet is inside the bounding box or intersects with it. */ + inline bool ContainedByOrIntersectBoundingBox(const Base::BoundBox3f& rcBB) const; + /** Checks if the facet intersects with the given bounding box. */ + bool IntersectBoundingBox(const Base::BoundBox3f& rclBB) const; + /** This method checks if both facets intersect. + */ + bool IntersectWithFacet(const MeshGeomFacet& rclFacet) const; + /** + * Intersect the facet with the other facet + * The result is line given by two points (if intersected). + * Return is the number of intersections points: 0: no intersection, 1: one intersection point + * (rclPt0), 2: two intersections points (rclPt0, rclPt1) + */ + int IntersectWithFacet(const MeshGeomFacet& facet, + Base::Vector3f& rclPt0, + Base::Vector3f& rclPt1) const; + /** Calculates the shortest distance from the line segment defined by \a rcP1 and \a rcP2 to + * this facet. + */ + float DistanceToLineSegment(const Base::Vector3f& rcP1, const Base::Vector3f& rcP2) const; + /** Calculates the shortest distance from the point \a rcPt to the facet. */ + float DistanceToPoint(const Base::Vector3f& rcPt) const + { + Base::Vector3f res; + return DistanceToPoint(rcPt, res); + } + /** Calculates the shortest distance from the point \a rcPt to the facet. \a rclNt is the point + * of the facet with shortest distance. + */ + float DistanceToPoint(const Base::Vector3f& rclPt, Base::Vector3f& rclNt) const; + /** Calculates the intersection point of the line defined by the base \a rclPt and the direction + * \a rclDir with the facet. The intersection must be inside the facet. If there is no + * intersection false is returned. + */ + bool IntersectWithLine(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + Base::Vector3f& rclRes) const; + /** Calculates the intersection point of the line defined by the base \a rclPt and the direction + * \a rclDir with the facet. The intersection must be inside the facet. If there is no + * intersection false is returned. This does actually the same as IntersectWithLine() with one + * additionally constraint that the angle between the direction of the line and the normal of + * the plane must not exceed \a fMaxAngle. + */ + bool Foraminate(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + Base::Vector3f& rclRes, + float fMaxAngle = Mathf::PI) const; + /** Checks if the facet intersects with the plane defined by the base \a rclBase and the normal + * \a rclNormal and returns true if two points are found, false otherwise. + */ + bool IntersectWithPlane(const Base::Vector3f& rclBase, + const Base::Vector3f& rclNormal, + Base::Vector3f& rclP1, + Base::Vector3f& rclP2) const; + /** + * Checks if the facet intersects with the plane defined by the base \a rclBase and the normal + * \a rclNormal. + */ + inline bool IntersectWithPlane(const Base::Vector3f& rclBase, + const Base::Vector3f& rclNormal) const; + /** Checks if the plane defined by the facet \a rclFacet intersects with the line defined by the + * base \a rclBase and the direction \a rclNormal and returns the intersection point \a rclRes + * if possible. + */ + bool IntersectPlaneWithLine(const Base::Vector3f& rclBase, + const Base::Vector3f& rclNormal, + Base::Vector3f& rclRes) const; + /** Calculates the volume of the prism defined by two facets. + * \note The two facets must not intersect. + */ + float VolumeOfPrism(const MeshGeomFacet& rclF) const; + /** Subsamples the facet into points with resolution \a fStep. */ + void SubSample(float fStep, std::vector& rclPoints) const; + /** Calculates the center and radius of the inscribed circle of the facet. */ + float CenterOfInscribedCircle(Base::Vector3f& rclCenter) const; + /** Calculates the center and radius of the circum circle of the facet. */ + float CenterOfCircumCircle(Base::Vector3f& rclCenter) const; + /** Returns the edge number of the facet that is nearest to the point \a rclPt. */ + unsigned short NearestEdgeToPoint(const Base::Vector3f& rclPt) const; + /** Returns the edge number \a side of the facet and the distance to the edge that is nearest to + * the point \a rclPt. */ + void + NearestEdgeToPoint(const Base::Vector3f& rclPt, float& fDistance, unsigned short& side) const; + /** Returns the edge for \a side. */ + MeshGeomEdge GetEdge(short side) const; + /** The center and radius of the circum circle define a sphere in 3D. If the point \a rP is part + * of this sphere true is returned, otherwise false. + */ + bool IsPointOfSphere(const Base::Vector3f& rP) const; + /** This is an overloaded member function, provided for convenience. It behaves essentially like + * the above function. If one of the facet's points is inside the sphere true is returned, + * otherwise false. + */ + bool IsPointOfSphere(const MeshGeomFacet& rFacet) const; + /** The aspect ratio is the longest edge length divided by its height. + */ + float AspectRatio() const; + /** The alternative aspect ration is the ratio of the radius of the circum-circle and twice the + * radius of the in-circle. + */ + float AspectRatio2() const; + /** The roundness is in the range between 0.0 (colinear) and 1.0 (equilateral). + */ + float Roundness() const; + /** Apply a transformation on the triangle. + */ + void Transform(const Base::Matrix4D&); + /** + * Checks if the two triangles are coplanar. + */ + bool IsCoplanar(const MeshGeomFacet& facet) const; protected: - mutable Base::Vector3f _clNormal; /**< Normal of the facet. */ - mutable bool _bNormalCalculated; /**< True if the normal is already calculated. */ + mutable Base::Vector3f _clNormal; /**< Normal of the facet. */ + mutable bool _bNormalCalculated; /**< True if the normal is already calculated. */ public: - Base::Vector3f _aclPoints[3]; /**< Geometric corner points. */ - unsigned char _ucFlag; /**< Flag property */ - unsigned long _ulProp; /**< Free usable property. */ + Base::Vector3f _aclPoints[3]; /**< Geometric corner points. */ + unsigned char _ucFlag; /**< Flag property */ + unsigned long _ulProp; /**< Free usable property. */ }; using TMeshPointArray = std::vector; @@ -582,52 +682,54 @@ using TMeshPointArray = std::vector; class MeshExport MeshPointArray: public TMeshPointArray { public: - // Iterator interface - using _TIterator = std::vector::iterator; - using _TConstIterator = std::vector::const_iterator; + // Iterator interface + using _TIterator = std::vector::iterator; + using _TConstIterator = std::vector::const_iterator; - /** @name Construction */ - //@{ - // constructor - MeshPointArray () = default; - // constructor - explicit MeshPointArray (PointIndex ulSize) : TMeshPointArray(ulSize) { } - /// copy-constructor - MeshPointArray (const MeshPointArray&); - MeshPointArray (MeshPointArray&&); - // Destructor - ~MeshPointArray () = default; - //@} + /** @name Construction */ + //@{ + // constructor + MeshPointArray() = default; + // constructor + explicit MeshPointArray(PointIndex ulSize) + : TMeshPointArray(ulSize) + {} + /// copy-constructor + MeshPointArray(const MeshPointArray&); + MeshPointArray(MeshPointArray&&); + // Destructor + ~MeshPointArray() = default; + //@} - /** @name Flag state - * @note All flag methods are const as they do NOT change the actual properties of the object - */ - //@{ - /// Sets the flag for all points - void SetFlag (MeshPoint::TFlagType tF) const; - /// Resets the flag for all points - void ResetFlag (MeshPoint::TFlagType tF) const; - /// Sets all points invalid - void ResetInvalid () const; - /// Sets the property for all points - void SetProperty (unsigned long ulVal) const; - //@} + /** @name Flag state + * @note All flag methods are const as they do NOT change the actual properties of the object + */ + //@{ + /// Sets the flag for all points + void SetFlag(MeshPoint::TFlagType tF) const; + /// Resets the flag for all points + void ResetFlag(MeshPoint::TFlagType tF) const; + /// Sets all points invalid + void ResetInvalid() const; + /// Sets the property for all points + void SetProperty(unsigned long ulVal) const; + //@} - // Assignment - MeshPointArray& operator = (const MeshPointArray &rclPAry); - MeshPointArray& operator = (MeshPointArray &&rclPAry); - void Transform(const Base::Matrix4D&); - /** - * Searches for the first point index Two points are equal if the distance is less - * than EPSILON. If no such points is found POINT_INDEX_MAX is returned. - */ - PointIndex Get (const MeshPoint &rclPoint); - /** - * Searches for the first point index Two points are equal if the distance is less - * than EPSILON. If no such points is found the point is added to the array at end - * and its index is returned. - */ - PointIndex GetOrAddIndex (const MeshPoint &rclPoint); + // Assignment + MeshPointArray& operator=(const MeshPointArray& rclPAry); + MeshPointArray& operator=(MeshPointArray&& rclPAry); + void Transform(const Base::Matrix4D&); + /** + * Searches for the first point index Two points are equal if the distance is less + * than EPSILON. If no such points is found POINT_INDEX_MAX is returned. + */ + PointIndex Get(const MeshPoint& rclPoint); + /** + * Searches for the first point index Two points are equal if the distance is less + * than EPSILON. If no such points is found the point is added to the array at end + * and its index is returned. + */ + PointIndex GetOrAddIndex(const MeshPoint& rclPoint); }; using TMeshFacetArray = std::vector; @@ -645,48 +747,50 @@ public: /** @name Construction */ //@{ /// constructor - MeshFacetArray () = default; + MeshFacetArray() = default; /// constructor - explicit MeshFacetArray (FacetIndex ulSize) : TMeshFacetArray(ulSize) { } + explicit MeshFacetArray(FacetIndex ulSize) + : TMeshFacetArray(ulSize) + {} /// copy-constructor - MeshFacetArray (const MeshFacetArray&); - MeshFacetArray (MeshFacetArray&&); + MeshFacetArray(const MeshFacetArray&); + MeshFacetArray(MeshFacetArray&&); /// destructor - ~MeshFacetArray () = default; + ~MeshFacetArray() = default; //@} /** @name Flag state - * @note All flag methods are const as they do NOT change the actual properties - * of the object - */ + * @note All flag methods are const as they do NOT change the actual properties + * of the object + */ //@{ /// Sets the flag for all facets. - void SetFlag (MeshFacet::TFlagType tF) const; + void SetFlag(MeshFacet::TFlagType tF) const; /// Resets the flag for all facets. - void ResetFlag (MeshFacet::TFlagType tF) const; + void ResetFlag(MeshFacet::TFlagType tF) const; /// Sets all facets invalid - void ResetInvalid () const; + void ResetInvalid() const; /// Sets the property for all facets - void SetProperty (unsigned long ulVal) const; + void SetProperty(unsigned long ulVal) const; //@} // Assignment - MeshFacetArray& operator = (const MeshFacetArray &rclFAry); - MeshFacetArray& operator = (MeshFacetArray &&rclFAry); + MeshFacetArray& operator=(const MeshFacetArray& rclFAry); + MeshFacetArray& operator=(MeshFacetArray&& rclFAry); /** * Removes the facet from the array the iterator points to. All neighbour * indices of the other facets get adjusted. */ - void Erase (_TIterator pIter); + void Erase(_TIterator pIter); /** * Checks and flips the point indices if needed. @see MeshFacet::Transpose(). */ - void TransposeIndices (PointIndex ulOrig, PointIndex ulNew); + void TransposeIndices(PointIndex ulOrig, PointIndex ulNew); /** * Decrements all point indices that are higher than \a ulIndex. */ - void DecrementIndices (PointIndex ulIndex); + void DecrementIndices(PointIndex ulIndex); }; /** @@ -698,17 +802,19 @@ class MeshExport MeshPointModifier public: explicit MeshPointModifier(MeshPointArray& points) : rPoints(points) - { - } + {} ~MeshPointModifier() = default; - MeshPointArray& GetPoints() const { return rPoints; } + MeshPointArray& GetPoints() const + { + return rPoints; + } MeshPointModifier(const MeshPointModifier& c) = default; MeshPointModifier(MeshPointModifier&& c) = default; - MeshPointModifier& operator = (const MeshPointModifier& c) = delete; - MeshPointModifier& operator = (MeshPointModifier&& c) = delete; + MeshPointModifier& operator=(const MeshPointModifier& c) = delete; + MeshPointModifier& operator=(MeshPointModifier&& c) = delete; private: MeshPointArray& rPoints; @@ -723,14 +829,13 @@ class MeshExport MeshFacetModifier public: explicit MeshFacetModifier(MeshFacetArray& facets) : rFacets(facets) - { - } + {} ~MeshFacetModifier() = default; MeshFacetModifier(const MeshFacetModifier& c) = default; MeshFacetModifier(MeshFacetModifier&& c) = default; - MeshFacetModifier& operator = (const MeshFacetModifier& c) = delete; - MeshFacetModifier& operator = (MeshFacetModifier&& c) = delete; + MeshFacetModifier& operator=(const MeshFacetModifier& c) = delete; + MeshFacetModifier& operator=(MeshFacetModifier&& c) = delete; /** * Replaces the index of the corner point of the facet at position \a pos @@ -746,151 +851,164 @@ private: MeshFacetArray& rFacets; }; -inline MeshPoint::MeshPoint (float x, float y, float z) - : Base::Vector3f(x, y, z), - _ucFlag(0), - _ulProp(0) -{ -} +inline MeshPoint::MeshPoint(float x, float y, float z) + : Base::Vector3f(x, y, z) + , _ucFlag(0) + , _ulProp(0) +{} -inline MeshPoint::MeshPoint (const Base::Vector3f &rclPt) - : Base::Vector3f(rclPt), - _ucFlag(0), - _ulProp(0) -{ -} +inline MeshPoint::MeshPoint(const Base::Vector3f& rclPt) + : Base::Vector3f(rclPt) + , _ucFlag(0) + , _ulProp(0) +{} -inline bool MeshPoint::operator == (const MeshPoint &rclPt) const +inline bool MeshPoint::operator==(const MeshPoint& rclPt) const { return Base::DistanceP2(*this, rclPt) < MeshDefinitions::_fMinPointDistanceP2; } -inline bool MeshPoint::operator == (const Base::Vector3f &rclV) const +inline bool MeshPoint::operator==(const Base::Vector3f& rclV) const { return Base::DistanceP2(*this, rclV) < MeshDefinitions::_fMinPointDistanceP2; } -inline bool MeshPoint::operator < (const MeshPoint &rclPt) const +inline bool MeshPoint::operator<(const MeshPoint& rclPt) const { - if (fabs ( this->x - rclPt.x ) >= MeshDefinitions::_fMinPointDistanceD1) + if (fabs(this->x - rclPt.x) >= MeshDefinitions::_fMinPointDistanceD1) { return this->x < rclPt.x; - if (fabs ( this->y - rclPt.y ) >= MeshDefinitions::_fMinPointDistanceD1) + } + if (fabs(this->y - rclPt.y) >= MeshDefinitions::_fMinPointDistanceD1) { return this->y < rclPt.y; - if (fabs ( this->z - rclPt.z ) >= MeshDefinitions::_fMinPointDistanceD1) + } + if (fabs(this->z - rclPt.z) >= MeshDefinitions::_fMinPointDistanceD1) { return this->z < rclPt.z; - return false; // points are considered to be equal + } + return false; // points are considered to be equal } -inline float MeshGeomFacet::DistancePlaneToPoint (const Base::Vector3f &rclPoint) const +inline float MeshGeomFacet::DistancePlaneToPoint(const Base::Vector3f& rclPoint) const { // internal normal is forced to have length equal to 1 return float(fabs(rclPoint.DistanceToPlane(_aclPoints[0], GetNormal()))); } -inline void MeshGeomFacet::CalcNormal () const +inline void MeshGeomFacet::CalcNormal() const { _clNormal = (_aclPoints[1] - _aclPoints[0]) % (_aclPoints[2] - _aclPoints[0]); _clNormal.Normalize(); _bNormalCalculated = true; } -inline Base::Vector3f MeshGeomFacet::GetNormal () const +inline Base::Vector3f MeshGeomFacet::GetNormal() const { - if (!_bNormalCalculated) + if (!_bNormalCalculated) { CalcNormal(); + } return _clNormal; } -inline void MeshGeomFacet::SetNormal (const Base::Vector3f &rclNormal) +inline void MeshGeomFacet::SetNormal(const Base::Vector3f& rclNormal) { - if (rclNormal.Sqr() == 0.0f) + if (rclNormal.Sqr() == 0.0f) { return; + } _clNormal = rclNormal; _clNormal.Normalize(); _bNormalCalculated = true; } -inline void MeshGeomFacet::ArrangeNormal (const Base::Vector3f &rclN) +inline void MeshGeomFacet::ArrangeNormal(const Base::Vector3f& rclN) { // force internal normal to be computed if not done yet - if ((rclN * GetNormal()) < 0.0f) + if ((rclN * GetNormal()) < 0.0f) { _clNormal = -_clNormal; + } } -inline Base::Vector3f MeshGeomFacet::GetGravityPoint () const +inline Base::Vector3f MeshGeomFacet::GetGravityPoint() const { return (1.0f / 3.0f) * (_aclPoints[0] + _aclPoints[1] + _aclPoints[2]); } -inline void MeshGeomFacet::AdjustCirculationDirection () +inline void MeshGeomFacet::AdjustCirculationDirection() { Base::Vector3f clN = (_aclPoints[1] - _aclPoints[0]) % (_aclPoints[2] - _aclPoints[0]); - if ((clN * _clNormal) < 0.0f) + if ((clN * _clNormal) < 0.0f) { std::swap(_aclPoints[1], _aclPoints[2]); + } } -inline Base::BoundBox3f MeshGeomFacet::GetBoundBox () const +inline Base::BoundBox3f MeshGeomFacet::GetBoundBox() const { return {_aclPoints, 3}; } inline float MeshGeomFacet::Perimeter() const { - float perimeter=0.0f; + float perimeter = 0.0f; perimeter += Base::Distance(_aclPoints[0], _aclPoints[1]); perimeter += Base::Distance(_aclPoints[1], _aclPoints[2]); perimeter += Base::Distance(_aclPoints[2], _aclPoints[0]); return perimeter; } -inline float MeshGeomFacet::Area () const +inline float MeshGeomFacet::Area() const { - return ((_aclPoints[1] - _aclPoints[0]) % - (_aclPoints[2] - _aclPoints[0])).Length() / 2.0f; + return ((_aclPoints[1] - _aclPoints[0]) % (_aclPoints[2] - _aclPoints[0])).Length() / 2.0f; } -inline bool MeshGeomFacet::ContainedByOrIntersectBoundingBox ( const Base::BoundBox3f &rclBB ) const +inline bool MeshGeomFacet::ContainedByOrIntersectBoundingBox(const Base::BoundBox3f& rclBB) const { - // Test, if all corner points of the facet are on one of the 6 sides of the BB - if (!(GetBoundBox() && rclBB)) + // Test, if all corner points of the facet are on one of the 6 sides of the BB + if (!(GetBoundBox() && rclBB)) { return false; + } // Test, whether Facet-BB is completely within BB - if (rclBB.IsInBox(GetBoundBox())) + if (rclBB.IsInBox(GetBoundBox())) { return true; + } // Test, whether one of the corner points is in BB for (auto pnt : _aclPoints) { - if (rclBB.IsInBox(pnt)) + if (rclBB.IsInBox(pnt)) { return true; + } } // "real" test for cutting - if (IntersectBoundingBox(rclBB)) + if (IntersectBoundingBox(rclBB)) { return true; + } return false; } -inline bool MeshGeomFacet::IntersectWithPlane (const Base::Vector3f &rclBase, const Base::Vector3f &rclNormal) const +inline bool MeshGeomFacet::IntersectWithPlane(const Base::Vector3f& rclBase, + const Base::Vector3f& rclNormal) const { bool bD0 = (_aclPoints[0].DistanceToPlane(rclBase, rclNormal) > 0.0f); - return !((bD0 == (_aclPoints[1].DistanceToPlane(rclBase, rclNormal) > 0.0f)) && - (bD0 == (_aclPoints[2].DistanceToPlane(rclBase, rclNormal) > 0.0f))); + return !((bD0 == (_aclPoints[1].DistanceToPlane(rclBase, rclNormal) > 0.0f)) + && (bD0 == (_aclPoints[2].DistanceToPlane(rclBase, rclNormal) > 0.0f))); } -inline MeshFacet::MeshFacet () -: _ucFlag(0), - _ulProp(0) +inline MeshFacet::MeshFacet() + : _ucFlag(0) + , _ulProp(0) { memset(_aulNeighbours, 0xff, sizeof(FacetIndex) * 3); memset(_aulPoints, 0xff, sizeof(PointIndex) * 3); } -inline MeshFacet::MeshFacet(PointIndex p1,PointIndex p2,PointIndex p3, - FacetIndex n1,FacetIndex n2,FacetIndex n3) -: _ucFlag(0), - _ulProp(0) +inline MeshFacet::MeshFacet(PointIndex p1, + PointIndex p2, + PointIndex p3, + FacetIndex n1, + FacetIndex n2, + FacetIndex n3) + : _ucFlag(0) + , _ulProp(0) { _aulPoints[0] = p1; _aulPoints[1] = p2; @@ -901,74 +1019,92 @@ inline MeshFacet::MeshFacet(PointIndex p1,PointIndex p2,PointIndex p3, _aulNeighbours[2] = n3; } -void MeshFacet::SetVertices(PointIndex p1,PointIndex p2,PointIndex p3) +void MeshFacet::SetVertices(PointIndex p1, PointIndex p2, PointIndex p3) { _aulPoints[0] = p1; _aulPoints[1] = p2; _aulPoints[2] = p3; } -void MeshFacet::SetNeighbours(FacetIndex n1,FacetIndex n2,FacetIndex n3) +void MeshFacet::SetNeighbours(FacetIndex n1, FacetIndex n2, FacetIndex n3) { _aulNeighbours[0] = n1; _aulNeighbours[1] = n2; _aulNeighbours[2] = n3; } -inline void MeshFacet::GetEdge (unsigned short usSide, MeshHelpEdge &rclEdge) const +inline void MeshFacet::GetEdge(unsigned short usSide, MeshHelpEdge& rclEdge) const { rclEdge._ulIndex[0] = _aulPoints[usSide]; - rclEdge._ulIndex[1] = _aulPoints[(usSide+1) % 3]; + rclEdge._ulIndex[1] = _aulPoints[(usSide + 1) % 3]; } -inline std::pair MeshFacet::GetEdge (unsigned short usSide) const +inline std::pair MeshFacet::GetEdge(unsigned short usSide) const { - return {_aulPoints[usSide], _aulPoints[(usSide+1)%3]}; + return {_aulPoints[usSide], _aulPoints[(usSide + 1) % 3]}; } -inline void MeshFacet::Transpose (PointIndex ulOrig, PointIndex ulNew) +inline void MeshFacet::Transpose(PointIndex ulOrig, PointIndex ulNew) { - if (_aulPoints[0] == ulOrig) + if (_aulPoints[0] == ulOrig) { _aulPoints[0] = ulNew; - else if (_aulPoints[1] == ulOrig) + } + else if (_aulPoints[1] == ulOrig) { _aulPoints[1] = ulNew; - else if (_aulPoints[2] == ulOrig) + } + else if (_aulPoints[2] == ulOrig) { _aulPoints[2] = ulNew; + } } -inline void MeshFacet::Decrement (PointIndex ulIndex) +inline void MeshFacet::Decrement(PointIndex ulIndex) { - if (_aulPoints[0] > ulIndex) _aulPoints[0]--; - if (_aulPoints[1] > ulIndex) _aulPoints[1]--; - if (_aulPoints[2] > ulIndex) _aulPoints[2]--; + if (_aulPoints[0] > ulIndex) { + _aulPoints[0]--; + } + if (_aulPoints[1] > ulIndex) { + _aulPoints[1]--; + } + if (_aulPoints[2] > ulIndex) { + _aulPoints[2]--; + } } inline bool MeshFacet::HasPoint(PointIndex ulIndex) const { - if (_aulPoints[0] == ulIndex) + if (_aulPoints[0] == ulIndex) { return true; - if (_aulPoints[1] == ulIndex) + } + if (_aulPoints[1] == ulIndex) { return true; - if (_aulPoints[2] == ulIndex) + } + if (_aulPoints[2] == ulIndex) { return true; + } return false; } -inline void MeshFacet::ReplaceNeighbour (FacetIndex ulOrig, FacetIndex ulNew) +inline void MeshFacet::ReplaceNeighbour(FacetIndex ulOrig, FacetIndex ulNew) { - if (_aulNeighbours[0] == ulOrig) + if (_aulNeighbours[0] == ulOrig) { _aulNeighbours[0] = ulNew; - else if (_aulNeighbours[1] == ulOrig) + } + else if (_aulNeighbours[1] == ulOrig) { _aulNeighbours[1] = ulNew; - else if (_aulNeighbours[2] == ulOrig) + } + else if (_aulNeighbours[2] == ulOrig) { _aulNeighbours[2] = ulNew; + } } inline unsigned short MeshFacet::CountOpenEdges() const { - unsigned short ct=0; - for (unsigned short i=0; i<3; i++) - { if ( !HasNeighbour(i) ) ct++; } + unsigned short ct = 0; + for (unsigned short i = 0; i < 3; i++) { + if (!HasNeighbour(i)) { + ct++; + } + } return ct; } @@ -982,8 +1118,8 @@ inline bool MeshFacet::HasSameOrientation(const MeshFacet& f) const for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (_aulPoints[i] == f._aulPoints[j]) { - if ((_aulPoints[(i+1)%3] == f._aulPoints[(j+1)%3]) || - (_aulPoints[(i+2)%3] == f._aulPoints[(j+2)%3])) { + if ((_aulPoints[(i + 1) % 3] == f._aulPoints[(j + 1) % 3]) + || (_aulPoints[(i + 2) % 3] == f._aulPoints[(j + 2) % 3])) { return false; } } @@ -995,73 +1131,89 @@ inline bool MeshFacet::HasSameOrientation(const MeshFacet& f) const inline bool MeshFacet::IsDegenerated() const { - if (_aulPoints[0] == _aulPoints[1]) + if (_aulPoints[0] == _aulPoints[1]) { return true; - if (_aulPoints[1] == _aulPoints[2]) + } + if (_aulPoints[1] == _aulPoints[2]) { return true; - if (_aulPoints[2] == _aulPoints[0]) + } + if (_aulPoints[2] == _aulPoints[0]) { return true; + } return false; } -inline unsigned short MeshFacet::Side (FacetIndex ulNIndex) const +inline unsigned short MeshFacet::Side(FacetIndex ulNIndex) const { - if (_aulNeighbours[0] == ulNIndex) + if (_aulNeighbours[0] == ulNIndex) { return 0; - else if (_aulNeighbours[1] == ulNIndex) + } + else if (_aulNeighbours[1] == ulNIndex) { return 1; - else if (_aulNeighbours[2] == ulNIndex) + } + else if (_aulNeighbours[2] == ulNIndex) { return 2; - else + } + else { return USHRT_MAX; + } } -inline unsigned short MeshFacet::Side (PointIndex ulP0, PointIndex ulP1) const +inline unsigned short MeshFacet::Side(PointIndex ulP0, PointIndex ulP1) const { if (_aulPoints[0] == ulP0) { - if (_aulPoints[1] == ulP1) + if (_aulPoints[1] == ulP1) { return 0; // Edge 0-1 ==> 0 - else if (_aulPoints[2] == ulP1) + } + else if (_aulPoints[2] == ulP1) { return 2; // Edge 0-2 ==> 2 + } } else if (_aulPoints[1] == ulP0) { - if (_aulPoints[0] == ulP1) - return 0; // Edge 1-0 ==> 0 - else if (_aulPoints[2] == ulP1) - return 1; // Edge 1-2 ==> 1 + if (_aulPoints[0] == ulP1) { + return 0; // Edge 1-0 ==> 0 + } + else if (_aulPoints[2] == ulP1) { + return 1; // Edge 1-2 ==> 1 + } } else if (_aulPoints[2] == ulP0) { - if (_aulPoints[0] == ulP1) - return 2; // Edge 2-0 ==> 2 - else if (_aulPoints[1] == ulP1) - return 1; // Edge 2-1 ==> 1 + if (_aulPoints[0] == ulP1) { + return 2; // Edge 2-0 ==> 2 + } + else if (_aulPoints[1] == ulP1) { + return 1; // Edge 2-1 ==> 1 + } } return USHRT_MAX; } -inline unsigned short MeshFacet::Side (const MeshFacet& rFace) const +inline unsigned short MeshFacet::Side(const MeshFacet& rFace) const { unsigned short side; - for (int i=0; i<3;i++){ - side = Side(rFace._aulPoints[i], rFace._aulPoints[(i+1)%3]); - if (side != USHRT_MAX) + for (int i = 0; i < 3; i++) { + side = Side(rFace._aulPoints[i], rFace._aulPoints[(i + 1) % 3]); + if (side != USHRT_MAX) { return side; + } } return USHRT_MAX; } -inline bool MeshFacet::IsEqual (const MeshFacet& rcFace) const +inline bool MeshFacet::IsEqual(const MeshFacet& rcFace) const { - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { if (this->_aulPoints[0] == rcFace._aulPoints[i]) { - if (this->_aulPoints[1] == rcFace._aulPoints[(i+1)%3] && - this->_aulPoints[2] == rcFace._aulPoints[(i+2)%3]) + if (this->_aulPoints[1] == rcFace._aulPoints[(i + 1) % 3] + && this->_aulPoints[2] == rcFace._aulPoints[(i + 2) % 3]) { return true; - else if (this->_aulPoints[1] == rcFace._aulPoints[(i+2)%3] && - this->_aulPoints[2] == rcFace._aulPoints[(i+1)%3]) + } + else if (this->_aulPoints[1] == rcFace._aulPoints[(i + 2) % 3] + && this->_aulPoints[2] == rcFace._aulPoints[(i + 1) % 3]) { return true; + } } } @@ -1071,59 +1223,69 @@ inline bool MeshFacet::IsEqual (const MeshFacet& rcFace) const /** * Binary function to query the flags for use with generic STL functions. */ -template +template class MeshIsFlag { public: using first_argument_type = TCLASS; using second_argument_type = typename TCLASS::TFlagType; using result_type = bool; - bool operator () (const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const - { return rclElem.IsFlag(tFlag); } + bool operator()(const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const + { + return rclElem.IsFlag(tFlag); + } }; /** * Binary function to query the flags for use with generic STL functions. */ -template +template class MeshIsNotFlag { public: using first_argument_type = TCLASS; using second_argument_type = typename TCLASS::TFlagType; using result_type = bool; - bool operator () (const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const - { return !rclElem.IsFlag(tFlag); } + bool operator()(const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const + { + return !rclElem.IsFlag(tFlag); + } }; /** * Binary function to set the flags for use with generic STL functions. */ -template +template class MeshSetFlag { public: using first_argument_type = TCLASS; using second_argument_type = typename TCLASS::TFlagType; using result_type = bool; - bool operator () (const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const - { rclElem.SetFlag(tFlag); return true; } + bool operator()(const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const + { + rclElem.SetFlag(tFlag); + return true; + } }; /** * Binary function to reset the flags for use with generic STL functions. */ -template +template class MeshResetFlag { public: using first_argument_type = TCLASS; using second_argument_type = typename TCLASS::TFlagType; using result_type = bool; - bool operator () (const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const - { rclElem.ResetFlag(tFlag); return true; } + bool operator()(const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const + { + rclElem.ResetFlag(tFlag); + return true; + } }; -} // namespace MeshCore +} // namespace MeshCore -#endif // MESH_ELEMENTS_H +#endif // MESH_ELEMENTS_H diff --git a/src/Mod/Mesh/App/Core/Evaluation.cpp b/src/Mod/Mesh/App/Core/Evaluation.cpp index 66307a66ab..707c712ceb 100644 --- a/src/Mod/Mesh/App/Core/Evaluation.cpp +++ b/src/Mod/Mesh/App/Core/Evaluation.cpp @@ -23,16 +23,16 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include +#include +#include #endif #include #include -#include "Evaluation.h" #include "Algorithm.h" #include "Approximation.h" +#include "Evaluation.h" #include "Functional.h" #include "Grid.h" #include "Iterator.h" @@ -44,8 +44,10 @@ using namespace MeshCore; MeshOrientationVisitor::MeshOrientationVisitor() = default; -bool MeshOrientationVisitor::Visit (const MeshFacet &rclFacet, const MeshFacet &rclFrom, - FacetIndex ulFInd, unsigned long ulLevel) +bool MeshOrientationVisitor::Visit(const MeshFacet& rclFacet, + const MeshFacet& rclFrom, + FacetIndex ulFInd, + unsigned long ulLevel) { (void)ulFInd; (void)ulLevel; @@ -62,13 +64,16 @@ bool MeshOrientationVisitor::HasNonUnifomOrientedFacets() const return _nonuniformOrientation; } -MeshOrientationCollector::MeshOrientationCollector(std::vector& aulIndices, std::vector& aulComplement) - : _aulIndices(aulIndices), _aulComplement(aulComplement) -{ -} +MeshOrientationCollector::MeshOrientationCollector(std::vector& aulIndices, + std::vector& aulComplement) + : _aulIndices(aulIndices) + , _aulComplement(aulComplement) +{} -bool MeshOrientationCollector::Visit (const MeshFacet &rclFacet, const MeshFacet &rclFrom, - FacetIndex ulFInd, unsigned long ulLevel) +bool MeshOrientationCollector::Visit(const MeshFacet& rclFacet, + const MeshFacet& rclFrom, + FacetIndex ulFInd, + unsigned long ulLevel) { (void)ulLevel; // different orientation of rclFacet and rclFrom @@ -77,10 +82,11 @@ bool MeshOrientationCollector::Visit (const MeshFacet &rclFacet, const MeshFacet if (!rclFrom.IsFlag(MeshFacet::TMP0)) { // mark this facet as false oriented rclFacet.SetFlag(MeshFacet::TMP0); - _aulIndices.push_back( ulFInd ); + _aulIndices.push_back(ulFInd); + } + else { + _aulComplement.push_back(ulFInd); } - else - _aulComplement.push_back( ulFInd ); } else { // same orientation but if the neighbour rclFrom is false oriented @@ -90,20 +96,22 @@ bool MeshOrientationCollector::Visit (const MeshFacet &rclFacet, const MeshFacet rclFacet.SetFlag(MeshFacet::TMP0); _aulIndices.push_back(ulFInd); } - else - _aulComplement.push_back( ulFInd ); + else { + _aulComplement.push_back(ulFInd); + } } return true; } MeshSameOrientationCollector::MeshSameOrientationCollector(std::vector& aulIndices) - : _aulIndices(aulIndices) -{ -} + : _aulIndices(aulIndices) +{} -bool MeshSameOrientationCollector::Visit (const MeshFacet &rclFacet, const MeshFacet &rclFrom, - FacetIndex ulFInd, unsigned long ulLevel) +bool MeshSameOrientationCollector::Visit(const MeshFacet& rclFacet, + const MeshFacet& rclFrom, + FacetIndex ulFInd, + unsigned long ulLevel) { // different orientation of rclFacet and rclFrom (void)ulLevel; @@ -116,12 +124,11 @@ bool MeshSameOrientationCollector::Visit (const MeshFacet &rclFacet, const MeshF // ---------------------------------------------------- -MeshEvalOrientation::MeshEvalOrientation (const MeshKernel& rclM) - : MeshEvaluation( rclM ) -{ -} +MeshEvalOrientation::MeshEvalOrientation(const MeshKernel& rclM) + : MeshEvaluation(rclM) +{} -bool MeshEvalOrientation::Evaluate () +bool MeshEvalOrientation::Evaluate() { const MeshFacetArray& rFAry = _rclMesh.GetFacets(); MeshFacetArray::_TConstIterator iBeg = rFAry.begin(); @@ -132,9 +139,9 @@ bool MeshEvalOrientation::Evaluate () const MeshFacet& rclFacet = iBeg[it->_aulNeighbours[i]]; for (int j = 0; j < 3; j++) { if (it->_aulPoints[i] == rclFacet._aulPoints[j]) { - if ((it->_aulPoints[(i+1)%3] == rclFacet._aulPoints[(j+1)%3]) || - (it->_aulPoints[(i+2)%3] == rclFacet._aulPoints[(j+2)%3])) { - return false; // adjacent face with wrong orientation + if ((it->_aulPoints[(i + 1) % 3] == rclFacet._aulPoints[(j + 1) % 3]) + || (it->_aulPoints[(i + 2) % 3] == rclFacet._aulPoints[(j + 2) % 3])) { + return false; // adjacent face with wrong orientation } } } @@ -147,12 +154,12 @@ bool MeshEvalOrientation::Evaluate () unsigned long MeshEvalOrientation::HasFalsePositives(const std::vector& inds) const { - // All faces with wrong orientation (i.e. adjacent faces with a normal flip and their neighbours) - // build a segment and are marked as TMP0. Now we check all border faces of the segments with - // their correct neighbours if there was really a normal flip. If there is no normal flip we have - // a false positive. - // False-positives can occur if the mesh structure has some defects which let the region-grow - // algorithm fail to detect the faces with wrong orientation. + // All faces with wrong orientation (i.e. adjacent faces with a normal flip and their + // neighbours) build a segment and are marked as TMP0. Now we check all border faces of the + // segments with their correct neighbours if there was really a normal flip. If there is no + // normal flip we have a false positive. False-positives can occur if the mesh structure has + // some defects which let the region-grow algorithm fail to detect the faces with wrong + // orientation. const MeshFacetArray& rFAry = _rclMesh.GetFacets(); MeshFacetArray::_TConstIterator iBeg = rFAry.begin(); for (FacetIndex it : inds) { @@ -179,8 +186,9 @@ std::vector MeshEvalOrientation::GetIndices() const { FacetIndex ulStartFacet, ulVisited; - if (_rclMesh.CountFacets() == 0) + if (_rclMesh.CountFacets() == 0) { return {}; + } // reset VISIT flags MeshAlgorithm cAlg(_rclMesh); @@ -197,18 +205,18 @@ std::vector MeshEvalOrientation::GetIndices() const std::vector uIndices, uComplement; MeshOrientationCollector clHarmonizer(uIndices, uComplement); - while (ulStartFacet != FACET_INDEX_MAX) { + while (ulStartFacet != FACET_INDEX_MAX) { unsigned long wrongFacets = uIndices.size(); uComplement.clear(); - uComplement.push_back( ulStartFacet ); + uComplement.push_back(ulStartFacet); ulVisited = _rclMesh.VisitNeighbourFacets(clHarmonizer, ulStartFacet) + 1; // In the currently visited component we have found less than 40% as correct // oriented and the rest as false oriented. So, we decide that it should be the other // way round and swap the indices of this component. - if (uComplement.size() < static_cast(0.4f*static_cast(ulVisited))) { - uIndices.erase(uIndices.begin()+wrongFacets, uIndices.end()); + if (uComplement.size() < static_cast(0.4f * static_cast(ulVisited))) { + uIndices.erase(uIndices.begin() + wrongFacets, uIndices.end()); uIndices.insert(uIndices.end(), uComplement.begin(), uComplement.end()); } @@ -220,10 +228,12 @@ std::vector MeshEvalOrientation::GetIndices() const return flag(f, MeshFacet::VISIT); }); - if (iTri < iEnd) + if (iTri < iEnd) { ulStartFacet = iTri - iBeg; - else + } + else { ulStartFacet = FACET_INDEX_MAX; + } } // in some very rare cases where we have some strange artifacts in the mesh structure @@ -241,27 +251,31 @@ std::vector MeshEvalOrientation::GetIndices() const std::sort(falsePos.begin(), falsePos.end()); std::vector diff; - std::back_insert_iterator > biit(diff); - std::set_difference(uIndices.begin(), uIndices.end(), falsePos.begin(), falsePos.end(), biit); + std::back_insert_iterator> biit(diff); + std::set_difference(uIndices.begin(), + uIndices.end(), + falsePos.begin(), + falsePos.end(), + biit); uIndices = diff; cAlg.ResetFacetFlag(MeshFacet::TMP0); cAlg.SetFacetsFlag(uIndices, MeshFacet::TMP0); FacetIndex current = ulStartFacet; ulStartFacet = HasFalsePositives(uIndices); - if (current == ulStartFacet) - break; // avoid an endless loop + if (current == ulStartFacet) { + break; // avoid an endless loop + } } return uIndices; } -MeshFixOrientation::MeshFixOrientation (MeshKernel& rclM) - : MeshValidation( rclM ) -{ -} +MeshFixOrientation::MeshFixOrientation(MeshKernel& rclM) + : MeshValidation(rclM) +{} -bool MeshFixOrientation::Fixup () +bool MeshFixOrientation::Fixup() { MeshTopoAlgorithm(_rclMesh).HarmonizeNormals(); return MeshEvalOrientation(_rclMesh).Evaluate(); @@ -269,27 +283,27 @@ bool MeshFixOrientation::Fixup () // ---------------------------------------------------- -MeshEvalSolid::MeshEvalSolid (const MeshKernel& rclM) - :MeshEvaluation( rclM ) -{ -} +MeshEvalSolid::MeshEvalSolid(const MeshKernel& rclM) + : MeshEvaluation(rclM) +{} -bool MeshEvalSolid::Evaluate () +bool MeshEvalSolid::Evaluate() { - std::vector edges; - _rclMesh.GetEdges( edges ); - for (const auto & it : edges) - { - if (it._bBorder) - return false; - } + std::vector edges; + _rclMesh.GetEdges(edges); + for (const auto& it : edges) { + if (it._bBorder) { + return false; + } + } - return true; + return true; } // ---------------------------------------------------- -namespace MeshCore { +namespace MeshCore +{ struct Edge_Index { @@ -301,27 +315,31 @@ struct Edge_Less { bool operator()(const Edge_Index& x, const Edge_Index& y) const { - if (x.p0 < y.p0) + if (x.p0 < y.p0) { return true; - else if (x.p0 > y.p0) + } + else if (x.p0 > y.p0) { return false; - else if (x.p1 < y.p1) + } + else if (x.p1 < y.p1) { return true; - else if (x.p1 > y.p1) + } + else if (x.p1 > y.p1) { return false; + } return false; } }; -} +} // namespace MeshCore -bool MeshEvalTopology::Evaluate () +bool MeshEvalTopology::Evaluate() { // Using and sorting a vector seems to be faster and more memory-efficient // than a map. const MeshFacetArray& rclFAry = _rclMesh.GetFacets(); std::vector edges; - edges.reserve(3*rclFAry.size()); + edges.reserve(3 * rclFAry.size()); // build up an array of edges MeshFacetArray::_TConstIterator pI; @@ -329,9 +347,9 @@ bool MeshEvalTopology::Evaluate () for (pI = rclFAry.begin(); pI != rclFAry.end(); ++pI) { for (int i = 0; i < 3; i++) { Edge_Index item; - item.p0 = std::min(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); - item.p1 = std::max(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); - item.f = pI - rclFAry.begin(); + item.p0 = std::min(pI->_aulPoints[i], pI->_aulPoints[(i + 1) % 3]); + item.p1 = std::max(pI->_aulPoints[i], pI->_aulPoints[(i + 1) % 3]); + item.f = pI - rclFAry.begin(); edges.push_back(item); } @@ -373,7 +391,7 @@ bool MeshEvalTopology::Evaluate () } // generate indexed edge list which tangents non-manifolds -void MeshEvalTopology::GetFacetManifolds (std::vector &raclFacetIndList) const +void MeshEvalTopology::GetFacetManifolds(std::vector& raclFacetIndList) const { raclFacetIndList.clear(); const MeshFacetArray& rclFAry = _rclMesh.GetFacets(); @@ -381,12 +399,14 @@ void MeshEvalTopology::GetFacetManifolds (std::vector &raclFacetIndL for (pI = rclFAry.begin(); pI != rclFAry.end(); ++pI) { for (int i = 0; i < 3; i++) { - PointIndex ulPt0 = std::min(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); - PointIndex ulPt1 = std::max(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); - std::pair edge = std::make_pair(ulPt0, ulPt1); + PointIndex ulPt0 = std::min(pI->_aulPoints[i], pI->_aulPoints[(i + 1) % 3]); + PointIndex ulPt1 = std::max(pI->_aulPoints[i], pI->_aulPoints[(i + 1) % 3]); + std::pair edge = std::make_pair(ulPt0, ulPt1); - if (std::find(nonManifoldList.begin(), nonManifoldList.end(), edge) != nonManifoldList.end()) + if (std::find(nonManifoldList.begin(), nonManifoldList.end(), edge) + != nonManifoldList.end()) { raclFacetIndList.push_back(pI - rclFAry.begin()); + } } } } @@ -396,7 +416,7 @@ unsigned long MeshEvalTopology::CountManifolds() const return nonManifoldList.size(); } -bool MeshFixTopology::Fixup () +bool MeshFixTopology::Fixup() { #if 0 MeshEvalTopology eval(_rclMesh); @@ -411,30 +431,35 @@ bool MeshFixTopology::Fixup () } #else const MeshFacetArray& rFaces = _rclMesh.GetFacets(); - deletedFaces.reserve(3 * nonManifoldList.size()); // allocate some memory + deletedFaces.reserve(3 * nonManifoldList.size()); // allocate some memory for (const auto& it : nonManifoldList) { std::vector non_mf; non_mf.reserve(it.size()); for (FacetIndex jt : it) { // facet is only connected with one edge and there causes a non-manifold unsigned short numOpenEdges = rFaces[jt].CountOpenEdges(); - if (numOpenEdges == 2) + if (numOpenEdges == 2) { non_mf.push_back(jt); - else if (rFaces[jt].IsDegenerated()) + } + else if (rFaces[jt].IsDegenerated()) { non_mf.push_back(jt); + } } // are we able to repair the non-manifold edge by not removing all facets? - if (it.size() - non_mf.size() == 2) + if (it.size() - non_mf.size() == 2) { deletedFaces.insert(deletedFaces.end(), non_mf.begin(), non_mf.end()); - else + } + else { deletedFaces.insert(deletedFaces.end(), it.begin(), it.end()); + } } if (!deletedFaces.empty()) { // remove duplicates std::sort(deletedFaces.begin(), deletedFaces.end()); - deletedFaces.erase(std::unique(deletedFaces.begin(), deletedFaces.end()), deletedFaces.end()); + deletedFaces.erase(std::unique(deletedFaces.begin(), deletedFaces.end()), + deletedFaces.end()); _rclMesh.DeleteFacets(deletedFaces); _rclMesh.RebuildNeighbours(); @@ -446,7 +471,7 @@ bool MeshFixTopology::Fixup () // --------------------------------------------------------- -bool MeshEvalPointManifolds::Evaluate () +bool MeshEvalPointManifolds::Evaluate() { this->nonManifoldPoints.clear(); this->facetsOfNonManifoldPoints.clear(); @@ -455,7 +480,7 @@ bool MeshEvalPointManifolds::Evaluate () MeshCore::MeshRefPointToFacets vf_it(_rclMesh); unsigned long ctPoints = _rclMesh.CountPoints(); - for (PointIndex index=0; index < ctPoints; index++) { + for (PointIndex index = 0; index < ctPoints; index++) { // get the local neighbourhood of the point const std::set& nf = vf_it[index]; const std::set& np = vv_it[index]; @@ -464,8 +489,9 @@ bool MeshEvalPointManifolds::Evaluate () sp = np.size(); sf = nf.size(); // for an inner point the number of adjacent points is equal to the number of shared faces - // for a boundary point the number of adjacent points is higher by one than the number of shared faces - // for a non-manifold point the number of adjacent points is higher by more than one than the number of shared faces + // for a boundary point the number of adjacent points is higher by one than the number of + // shared faces for a non-manifold point the number of adjacent points is higher by more + // than one than the number of shared faces if (sp > sf + 1) { nonManifoldPoints.push_back(index); std::vector faces; @@ -477,9 +503,9 @@ bool MeshEvalPointManifolds::Evaluate () return this->nonManifoldPoints.empty(); } -void MeshEvalPointManifolds::GetFacetIndices (std::vector &facets) const +void MeshEvalPointManifolds::GetFacetIndices(std::vector& facets) const { - std::list >::const_iterator it; + std::list>::const_iterator it; for (it = facetsOfNonManifoldPoints.begin(); it != facetsOfNonManifoldPoints.end(); ++it) { facets.insert(facets.end(), it->begin(), it->end()); } @@ -493,86 +519,86 @@ void MeshEvalPointManifolds::GetFacetIndices (std::vector &facets) c // --------------------------------------------------------- -bool MeshEvalSingleFacet::Evaluate () +bool MeshEvalSingleFacet::Evaluate() { - // get all non-manifolds - (void)MeshEvalTopology::Evaluate(); -/* - // for each (multiple) single linked facet there should - // exist two valid facets sharing the same edge - // so make facet 1 neighbour of facet 2 and vice versa - const std::vector& rclFAry = _rclMesh.GetFacets(); - std::vector::const_iterator pI; + // get all non-manifolds + (void)MeshEvalTopology::Evaluate(); + /* + // for each (multiple) single linked facet there should + // exist two valid facets sharing the same edge + // so make facet 1 neighbour of facet 2 and vice versa + const std::vector& rclFAry = _rclMesh.GetFacets(); + std::vector::const_iterator pI; - std::vector > aclMf = _aclManifoldList; - _aclManifoldList.clear(); + std::vector > aclMf = _aclManifoldList; + _aclManifoldList.clear(); - std::map, std::list > aclHits; - std::map, std::list >::iterator pEdge; + std::map, std::list > aclHits; + std::map, std::list >::iterator pEdge; - // search for single links (a non-manifold edge and two open edges) - // - // - // build edge <=> facet map - for (pI = rclFAry.begin(); pI != rclFAry.end(); ++pI) - { - for (int i = 0; i < 3; i++) - { - unsigned long ulPt0 = std::min(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); - unsigned long ulPt1 = std::max(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); - aclHits[std::pair(ulPt0, ulPt1)].push_front(pI - rclFAry.begin()); - } - } - - // now search for single links - for (std::vector >::const_iterator pMF = aclMf.begin(); pMF != aclMf.end(); ++pMF) - { - std::list aulManifolds; - for (std::list::const_iterator pF = pMF->begin(); pF != pMF->end(); ++pF) - { - const MeshFacet& rclF = rclFAry[*pF]; - - unsigned long ulCtNeighbours=0; - for (int i = 0; i < 3; i++) + // search for single links (a non-manifold edge and two open edges) + // + // + // build edge <=> facet map + for (pI = rclFAry.begin(); pI != rclFAry.end(); ++pI) { - unsigned long ulPt0 = std::min(rclF._aulPoints[i], rclF._aulPoints[(i+1)%3]); - unsigned long ulPt1 = std::max(rclF._aulPoints[i], rclF._aulPoints[(i+1)%3]); - std::pair clEdge(ulPt0, ulPt1); - - // number of facets sharing this edge - ulCtNeighbours += aclHits[clEdge].size(); + for (int i = 0; i < 3; i++) + { + unsigned long ulPt0 = std::min(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); + unsigned long ulPt1 = std::max(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); + aclHits[std::pair(ulPt0, ulPt1)].push_front(pI - + rclFAry.begin()); + } } - // single linked found - if (ulCtNeighbours == pMF->size() + 2) - aulManifolds.push_front(*pF); - } + // now search for single links + for (std::vector >::const_iterator pMF = aclMf.begin(); pMF != + aclMf.end(); ++pMF) + { + std::list aulManifolds; + for (std::list::const_iterator pF = pMF->begin(); pF != pMF->end(); ++pF) + { + const MeshFacet& rclF = rclFAry[*pF]; - if ( aulManifolds.size() > 0 ) - _aclManifoldList.push_back(aulManifolds); - } -*/ - return (nonManifoldList.empty()); + unsigned long ulCtNeighbours=0; + for (int i = 0; i < 3; i++) + { + unsigned long ulPt0 = std::min(rclF._aulPoints[i], + rclF._aulPoints[(i+1)%3]); unsigned long ulPt1 = std::max(rclF._aulPoints[i], + rclF._aulPoints[(i+1)%3]); std::pair clEdge(ulPt0, ulPt1); + + // number of facets sharing this edge + ulCtNeighbours += aclHits[clEdge].size(); + } + + // single linked found + if (ulCtNeighbours == pMF->size() + 2) + aulManifolds.push_front(*pF); + } + + if ( aulManifolds.size() > 0 ) + _aclManifoldList.push_back(aulManifolds); + } + */ + return (nonManifoldList.empty()); } -bool MeshFixSingleFacet::Fixup () +bool MeshFixSingleFacet::Fixup() { - std::vector aulInvalids; - for (const auto & it : _raclManifoldList) - { - for (FacetIndex it2 : it) - { - aulInvalids.push_back(it2); + std::vector aulInvalids; + for (const auto& it : _raclManifoldList) { + for (FacetIndex it2 : it) { + aulInvalids.push_back(it2); + } } - } - _rclMesh.DeleteFacets(aulInvalids); - return true; + _rclMesh.DeleteFacets(aulInvalids); + return true; } // ---------------------------------------------------------------- -bool MeshEvalSelfIntersection::Evaluate () +bool MeshEvalSelfIntersection::Evaluate() { // Contains bounding boxes for every facet std::vector boxes; @@ -590,42 +616,49 @@ bool MeshEvalSelfIntersection::Evaluate () } // Calculates the intersections - Base::SequencerLauncher seq("Checking for self-intersections...", ulGridX*ulGridY*ulGridZ); + Base::SequencerLauncher seq("Checking for self-intersections...", ulGridX * ulGridY * ulGridZ); for (clGridIter.Init(); clGridIter.More(); clGridIter.Next()) { - //Get the facet indices, belonging to the current grid unit + // Get the facet indices, belonging to the current grid unit std::vector aulGridElements; clGridIter.GetElements(aulGridElements); seq.next(); - if (aulGridElements.empty()) + if (aulGridElements.empty()) { continue; + } MeshGeomFacet facet1, facet2; Base::Vector3f pt1, pt2; - for (std::vector::iterator it = aulGridElements.begin(); it != aulGridElements.end(); ++it) { + for (std::vector::iterator it = aulGridElements.begin(); + it != aulGridElements.end(); + ++it) { const Base::BoundBox3f& box1 = boxes[*it]; cMFI.Set(*it); facet1 = *cMFI; const MeshFacet& rface1 = rFaces[*it]; for (std::vector::iterator jt = it; jt != aulGridElements.end(); ++jt) { - if (jt == it) // the identical facet + if (jt == it) { // the identical facet continue; - // If the facets share a common vertex we do not check for self-intersections because they - // could but usually do not intersect each other and the algorithm below would detect false-positives, - // otherwise + } + // If the facets share a common vertex we do not check for self-intersections + // because they could but usually do not intersect each other and the algorithm + // below would detect false-positives, otherwise const MeshFacet& rface2 = rFaces[*jt]; - if (rface1._aulPoints[0] == rface2._aulPoints[0] || - rface1._aulPoints[0] == rface2._aulPoints[1] || - rface1._aulPoints[0] == rface2._aulPoints[2]) - continue; // ignore facets sharing a common vertex - if (rface1._aulPoints[1] == rface2._aulPoints[0] || - rface1._aulPoints[1] == rface2._aulPoints[1] || - rface1._aulPoints[1] == rface2._aulPoints[2]) - continue; // ignore facets sharing a common vertex - if (rface1._aulPoints[2] == rface2._aulPoints[0] || - rface1._aulPoints[2] == rface2._aulPoints[1] || - rface1._aulPoints[2] == rface2._aulPoints[2]) - continue; // ignore facets sharing a common vertex + if (rface1._aulPoints[0] == rface2._aulPoints[0] + || rface1._aulPoints[0] == rface2._aulPoints[1] + || rface1._aulPoints[0] == rface2._aulPoints[2]) { + continue; // ignore facets sharing a common vertex + } + if (rface1._aulPoints[1] == rface2._aulPoints[0] + || rface1._aulPoints[1] == rface2._aulPoints[1] + || rface1._aulPoints[1] == rface2._aulPoints[2]) { + continue; // ignore facets sharing a common vertex + } + if (rface1._aulPoints[2] == rface2._aulPoints[0] + || rface1._aulPoints[2] == rface2._aulPoints[1] + || rface1._aulPoints[2] == rface2._aulPoints[2]) { + continue; // ignore facets sharing a common vertex + } const Base::BoundBox3f& box2 = boxes[*jt]; if (box1 && box2) { @@ -644,15 +677,16 @@ bool MeshEvalSelfIntersection::Evaluate () return true; } -void MeshEvalSelfIntersection::GetIntersections(const std::vector >& indices, - std::vector >& intersection) const +void MeshEvalSelfIntersection::GetIntersections( + const std::vector>& indices, + std::vector>& intersection) const { intersection.reserve(indices.size()); MeshFacetIterator cMF1(_rclMesh); MeshFacetIterator cMF2(_rclMesh); Base::Vector3f pt1, pt2; - std::vector >::const_iterator it; + std::vector>::const_iterator it; for (it = indices.begin(); it != indices.end(); ++it) { cMF1.Set(it->first); cMF2.Set(it->second); @@ -668,11 +702,12 @@ void MeshEvalSelfIntersection::GetIntersections(const std::vector >& intersection) const +void MeshEvalSelfIntersection::GetIntersections( + std::vector>& intersection) const { // Contains bounding boxes for every facet std::vector boxes; - //intersection.clear(); + // intersection.clear(); // Splits the mesh using grid for speeding up the calculation MeshFacetGrid cMeshFacetGrid(_rclMesh); @@ -682,47 +717,54 @@ void MeshEvalSelfIntersection::GetIntersections(std::vector aulGridElements; clGridIter.GetElements(aulGridElements); seq.next(true); - if (aulGridElements.empty()) + if (aulGridElements.empty()) { continue; + } MeshGeomFacet facet1, facet2; Base::Vector3f pt1, pt2; - for (std::vector::iterator it = aulGridElements.begin(); it != aulGridElements.end(); ++it) { + for (std::vector::iterator it = aulGridElements.begin(); + it != aulGridElements.end(); + ++it) { const Base::BoundBox3f& box1 = boxes[*it]; cMFI.Set(*it); facet1 = *cMFI; const MeshFacet& rface1 = rFaces[*it]; for (std::vector::iterator jt = it; jt != aulGridElements.end(); ++jt) { - if (jt == it) // the identical facet + if (jt == it) { // the identical facet continue; - // If the facets share a common vertex we do not check for self-intersections because they - // could but usually do not intersect each other and the algorithm below would detect false-positives, - // otherwise + } + // If the facets share a common vertex we do not check for self-intersections + // because they could but usually do not intersect each other and the algorithm + // below would detect false-positives, otherwise const MeshFacet& rface2 = rFaces[*jt]; - if (rface1._aulPoints[0] == rface2._aulPoints[0] || - rface1._aulPoints[0] == rface2._aulPoints[1] || - rface1._aulPoints[0] == rface2._aulPoints[2]) - continue; // ignore facets sharing a common vertex - if (rface1._aulPoints[1] == rface2._aulPoints[0] || - rface1._aulPoints[1] == rface2._aulPoints[1] || - rface1._aulPoints[1] == rface2._aulPoints[2]) - continue; // ignore facets sharing a common vertex - if (rface1._aulPoints[2] == rface2._aulPoints[0] || - rface1._aulPoints[2] == rface2._aulPoints[1] || - rface1._aulPoints[2] == rface2._aulPoints[2]) - continue; // ignore facets sharing a common vertex + if (rface1._aulPoints[0] == rface2._aulPoints[0] + || rface1._aulPoints[0] == rface2._aulPoints[1] + || rface1._aulPoints[0] == rface2._aulPoints[2]) { + continue; // ignore facets sharing a common vertex + } + if (rface1._aulPoints[1] == rface2._aulPoints[0] + || rface1._aulPoints[1] == rface2._aulPoints[1] + || rface1._aulPoints[1] == rface2._aulPoints[2]) { + continue; // ignore facets sharing a common vertex + } + if (rface1._aulPoints[2] == rface2._aulPoints[0] + || rface1._aulPoints[2] == rface2._aulPoints[1] + || rface1._aulPoints[2] == rface2._aulPoints[2]) { + continue; // ignore facets sharing a common vertex + } const Base::BoundBox3f& box2 = boxes[*jt]; if (box1 && box2) { @@ -730,7 +772,7 @@ void MeshEvalSelfIntersection::GetIntersections(std::vector MeshFixSelfIntersection::GetFacets() const { std::vector indices; const MeshFacetArray& rFaces = _rclMesh.GetFacets(); - for (const auto & it : selfIntersectons) { + for (const auto& it : selfIntersectons) { unsigned short numOpenEdges1 = rFaces[it.first].CountOpenEdges(); unsigned short numOpenEdges2 = rFaces[it.second].CountOpenEdges(); @@ -775,7 +817,7 @@ bool MeshFixSelfIntersection::Fixup() // ---------------------------------------------------------------- -bool MeshEvalNeighbourhood::Evaluate () +bool MeshEvalNeighbourhood::Evaluate() { // Note: If more than two facets are attached to the edge then we have a // non-manifold edge here. @@ -789,7 +831,7 @@ bool MeshEvalNeighbourhood::Evaluate () // than a map. const MeshFacetArray& rclFAry = _rclMesh.GetFacets(); std::vector edges; - edges.reserve(3*rclFAry.size()); + edges.reserve(3 * rclFAry.size()); // build up an array of edges MeshFacetArray::_TConstIterator pI; @@ -797,9 +839,9 @@ bool MeshEvalNeighbourhood::Evaluate () for (pI = rclFAry.begin(); pI != rclFAry.end(); ++pI) { for (int i = 0; i < 3; i++) { Edge_Index item; - item.p0 = std::min(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); - item.p1 = std::max(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); - item.f = pI - rclFAry.begin(); + item.p0 = std::min(pI->_aulPoints[i], pI->_aulPoints[(i + 1) % 3]); + item.p1 = std::max(pI->_aulPoints[i], pI->_aulPoints[(i + 1) % 3]); + item.f = pI - rclFAry.begin(); edges.push_back(item); } @@ -824,20 +866,21 @@ bool MeshEvalNeighbourhood::Evaluate () if (count == 2) { const MeshFacet& rFace0 = rclFAry[f0]; const MeshFacet& rFace1 = rclFAry[f1]; - unsigned short side0 = rFace0.Side(p0,p1); - unsigned short side1 = rFace1.Side(p0,p1); + unsigned short side0 = rFace0.Side(p0, p1); + unsigned short side1 = rFace1.Side(p0, p1); // Check whether rFace0 and rFace1 reference each other as // neighbours - if (rFace0._aulNeighbours[side0]!=f1 || - rFace1._aulNeighbours[side1]!=f0) + if (rFace0._aulNeighbours[side0] != f1 || rFace1._aulNeighbours[side1] != f0) { return false; + } } else if (count == 1) { const MeshFacet& rFace = rclFAry[f0]; - unsigned short side = rFace.Side(p0,p1); + unsigned short side = rFace.Side(p0, p1); // should be "open edge" but isn't marked as such - if (rFace._aulNeighbours[side] != FACET_INDEX_MAX) + if (rFace._aulNeighbours[side] != FACET_INDEX_MAX) { return false; + } } p0 = pE->p0; @@ -855,7 +898,7 @@ std::vector MeshEvalNeighbourhood::GetIndices() const std::vector inds; const MeshFacetArray& rclFAry = _rclMesh.GetFacets(); std::vector edges; - edges.reserve(3*rclFAry.size()); + edges.reserve(3 * rclFAry.size()); // build up an array of edges MeshFacetArray::_TConstIterator pI; @@ -863,9 +906,9 @@ std::vector MeshEvalNeighbourhood::GetIndices() const for (pI = rclFAry.begin(); pI != rclFAry.end(); ++pI) { for (int i = 0; i < 3; i++) { Edge_Index item; - item.p0 = std::min(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); - item.p1 = std::max(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); - item.f = pI - rclFAry.begin(); + item.p0 = std::min(pI->_aulPoints[i], pI->_aulPoints[(i + 1) % 3]); + item.p1 = std::max(pI->_aulPoints[i], pI->_aulPoints[(i + 1) % 3]); + item.f = pI - rclFAry.begin(); edges.push_back(item); } @@ -890,22 +933,22 @@ std::vector MeshEvalNeighbourhood::GetIndices() const if (count == 2) { const MeshFacet& rFace0 = rclFAry[f0]; const MeshFacet& rFace1 = rclFAry[f1]; - unsigned short side0 = rFace0.Side(p0,p1); - unsigned short side1 = rFace1.Side(p0,p1); + unsigned short side0 = rFace0.Side(p0, p1); + unsigned short side1 = rFace1.Side(p0, p1); // Check whether rFace0 and rFace1 reference each other as // neighbours - if (rFace0._aulNeighbours[side0]!=f1 || - rFace1._aulNeighbours[side1]!=f0) { + if (rFace0._aulNeighbours[side0] != f1 || rFace1._aulNeighbours[side1] != f0) { inds.push_back(f0); inds.push_back(f1); } } else if (count == 1) { const MeshFacet& rFace = rclFAry[f0]; - unsigned short side = rFace.Side(p0,p1); + unsigned short side = rFace.Side(p0, p1); // should be "open edge" but isn't marked as such - if (rFace._aulNeighbours[side] != FACET_INDEX_MAX) + if (rFace._aulNeighbours[side] != FACET_INDEX_MAX) { inds.push_back(f0); + } } p0 = pE->p0; @@ -928,7 +971,7 @@ bool MeshFixNeighbourhood::Fixup() return true; } -void MeshKernel::RebuildNeighbours (FacetIndex index) +void MeshKernel::RebuildNeighbours(FacetIndex index) { std::vector edges; edges.reserve(3 * (this->_aclFacetArray.size() - index)); @@ -939,15 +982,15 @@ void MeshKernel::RebuildNeighbours (FacetIndex index) for (pI = pB + index; pI != this->_aclFacetArray.end(); ++pI) { for (int i = 0; i < 3; i++) { Edge_Index item; - item.p0 = std::min(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); - item.p1 = std::max(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); - item.f = pI - pB; + item.p0 = std::min(pI->_aulPoints[i], pI->_aulPoints[(i + 1) % 3]); + item.p1 = std::max(pI->_aulPoints[i], pI->_aulPoints[(i + 1) % 3]); + item.f = pI - pB; edges.push_back(item); } } // sort the edges - //std::sort(edges.begin(), edges.end(), Edge_Less()); + // std::sort(edges.begin(), edges.end(), Edge_Less()); int threads = QThread::idealThreadCount(); MeshCore::parallel_sort(edges.begin(), edges.end(), Edge_Less(), threads); @@ -966,14 +1009,14 @@ void MeshKernel::RebuildNeighbours (FacetIndex index) if (count == 2) { MeshFacet& rFace0 = this->_aclFacetArray[f0]; MeshFacet& rFace1 = this->_aclFacetArray[f1]; - unsigned short side0 = rFace0.Side(p0,p1); - unsigned short side1 = rFace1.Side(p0,p1); + unsigned short side0 = rFace0.Side(p0, p1); + unsigned short side1 = rFace1.Side(p0, p1); rFace0._aulNeighbours[side0] = f1; rFace1._aulNeighbours[side1] = f0; } else if (count == 1) { MeshFacet& rFace = this->_aclFacetArray[f0]; - unsigned short side = rFace.Side(p0,p1); + unsigned short side = rFace.Side(p0, p1); rFace._aulNeighbours[side] = FACET_INDEX_MAX; } @@ -989,19 +1032,19 @@ void MeshKernel::RebuildNeighbours (FacetIndex index) if (count == 2) { MeshFacet& rFace0 = this->_aclFacetArray[f0]; MeshFacet& rFace1 = this->_aclFacetArray[f1]; - unsigned short side0 = rFace0.Side(p0,p1); - unsigned short side1 = rFace1.Side(p0,p1); + unsigned short side0 = rFace0.Side(p0, p1); + unsigned short side1 = rFace1.Side(p0, p1); rFace0._aulNeighbours[side0] = f1; rFace1._aulNeighbours[side1] = f0; } else if (count == 1) { MeshFacet& rFace = this->_aclFacetArray[f0]; - unsigned short side = rFace.Side(p0,p1); + unsigned short side = rFace.Side(p0, p1); rFace._aulNeighbours[side] = FACET_INDEX_MAX; } } -void MeshKernel::RebuildNeighbours () +void MeshKernel::RebuildNeighbours() { // complete rebuild RebuildNeighbours(0); @@ -1009,8 +1052,11 @@ void MeshKernel::RebuildNeighbours () // ---------------------------------------------------------------- -MeshEigensystem::MeshEigensystem (const MeshKernel &rclB) - : MeshEvaluation(rclB), _cU(1.0f, 0.0f, 0.0f), _cV(0.0f, 1.0f, 0.0f), _cW(0.0f, 0.0f, 1.0f) +MeshEigensystem::MeshEigensystem(const MeshKernel& rclB) + : MeshEvaluation(rclB) + , _cU(1.0f, 0.0f, 0.0f) + , _cV(0.0f, 1.0f, 0.0f) + , _cW(0.0f, 0.0f, 1.0f) { // use the values of world coordinates as default Base::BoundBox3f box = _rclMesh.GetBoundBox(); @@ -1030,16 +1076,30 @@ Base::Matrix4D MeshEigensystem::Transform() const // x = Q * y - Q * c Base::Matrix4D clTMat; // rotation part - clTMat[0][0] = double(_cU.x); clTMat[0][1] = double(_cU.y); clTMat[0][2] = double(_cU.z); clTMat[0][3] = 0.0; - clTMat[1][0] = double(_cV.x); clTMat[1][1] = double(_cV.y); clTMat[1][2] = double(_cV.z); clTMat[1][3] = 0.0; - clTMat[2][0] = double(_cW.x); clTMat[2][1] = double(_cW.y); clTMat[2][2] = double(_cW.z); clTMat[2][3] = 0.0; - clTMat[3][0] = 0.0; clTMat[3][1] = 0.0; clTMat[3][2] = 0.0; clTMat[3][3] = 1.0; + clTMat[0][0] = double(_cU.x); + clTMat[0][1] = double(_cU.y); + clTMat[0][2] = double(_cU.z); + clTMat[0][3] = 0.0; + clTMat[1][0] = double(_cV.x); + clTMat[1][1] = double(_cV.y); + clTMat[1][2] = double(_cV.z); + clTMat[1][3] = 0.0; + clTMat[2][0] = double(_cW.x); + clTMat[2][1] = double(_cW.y); + clTMat[2][2] = double(_cW.z); + clTMat[2][3] = 0.0; + clTMat[3][0] = 0.0; + clTMat[3][1] = 0.0; + clTMat[3][2] = 0.0; + clTMat[3][3] = 1.0; Base::Vector3f c(_cC); c = clTMat * c; // translation part - clTMat[0][3] = double(-c.x); clTMat[1][3] = double(-c.y); clTMat[2][3] = double(-c.z); + clTMat[0][3] = double(-c.x); + clTMat[1][3] = double(-c.y); + clTMat[2][3] = double(-c.z); return clTMat; } @@ -1048,13 +1108,13 @@ bool MeshEigensystem::Evaluate() { CalculateLocalSystem(); - float xmin=0.0f, xmax=0.0f, ymin=0.0f, ymax=0.0f, zmin=0.0f, zmax=0.0f; + float xmin = 0.0f, xmax = 0.0f, ymin = 0.0f, ymax = 0.0f, zmin = 0.0f, zmax = 0.0f; Base::Vector3f clVect, clProj; float fH; - const MeshPointArray& aclPoints = _rclMesh.GetPoints (); - for (const auto & it : aclPoints) { + const MeshPointArray& aclPoints = _rclMesh.GetPoints(); + for (const auto& it : aclPoints) { // u-direction clVect = it - _cC; clProj.ProjectToLine(clVect, _cU); @@ -1062,8 +1122,9 @@ bool MeshEigensystem::Evaluate() fH = clVect.Length(); // point vectors in the same direction ? - if ((clVect * _cU) < 0.0f) + if ((clVect * _cU) < 0.0f) { fH = -fH; + } xmax = std::max(xmax, fH); xmin = std::min(xmin, fH); @@ -1075,8 +1136,9 @@ bool MeshEigensystem::Evaluate() fH = clVect.Length(); // point vectors in the same direction ? - if ((clVect * _cV) < 0.0f) - fH = -fH; + if ((clVect * _cV) < 0.0f) { + fH = -fH; + } ymax = std::max(ymax, fH); ymin = std::min(ymin, fH); @@ -1088,8 +1150,9 @@ bool MeshEigensystem::Evaluate() fH = clVect.Length(); // point vectors in the same direction ? - if ((clVect * _cW) < 0.0f) + if ((clVect * _cW) < 0.0f) { fH = -fH; + } zmax = std::max(zmax, fH); zmin = std::min(zmin, fH); @@ -1099,26 +1162,28 @@ bool MeshEigensystem::Evaluate() _fV = ymax - ymin; _fW = zmax - zmin; - return false; // to call Fixup() if needed + return false; // to call Fixup() if needed } Base::Vector3f MeshEigensystem::GetBoundings() const { - return Base::Vector3f ( _fU, _fV, _fW ); + return Base::Vector3f(_fU, _fV, _fW); } void MeshEigensystem::CalculateLocalSystem() { // at least one facet is needed - if (_rclMesh.CountFacets() < 1) - return; // cannot continue calculation + if (_rclMesh.CountFacets() < 1) { + return; // cannot continue calculation + } - const MeshPointArray& aclPoints = _rclMesh.GetPoints (); + const MeshPointArray& aclPoints = _rclMesh.GetPoints(); MeshPointArray::_TConstIterator it; PlaneFit planeFit; - for (it = aclPoints.begin(); it!=aclPoints.end(); ++it) + for (it = aclPoints.begin(); it != aclPoints.end(); ++it) { planeFit.AddPoint(*it); + } planeFit.Fit(); _cC = planeFit.GetBase(); @@ -1129,8 +1194,7 @@ void MeshEigensystem::CalculateLocalSystem() // set the sign for the vectors float fSumU, fSumV, fSumW; fSumU = fSumV = fSumW = 0.0f; - for (it = aclPoints.begin(); it!=aclPoints.end(); ++it) - { + for (it = aclPoints.begin(); it != aclPoints.end(); ++it) { float fU = _cU * (*it - _cC); float fV = _cV * (*it - _cC); float fW = _cW * (*it - _cC); @@ -1140,13 +1204,17 @@ void MeshEigensystem::CalculateLocalSystem() } // avoid ambiguities concerning directions - if (fSumU < 0.0f) + if (fSumU < 0.0f) { _cU *= -1.0f; - if (fSumV < 0.0f) + } + if (fSumV < 0.0f) { _cV *= -1.0f; - if (fSumW < 0.0f) + } + if (fSumW < 0.0f) { _cW *= -1.0f; + } - if ((_cU%_cV)*_cW < 0.0f) - _cW = -_cW; // make a right-handed system + if ((_cU % _cV) * _cW < 0.0f) { + _cW = -_cW; // make a right-handed system + } } diff --git a/src/Mod/Mesh/App/Core/Evaluation.h b/src/Mod/Mesh/App/Core/Evaluation.h index 4d0bc52400..366e152e8f 100644 --- a/src/Mod/Mesh/App/Core/Evaluation.h +++ b/src/Mod/Mesh/App/Core/Evaluation.h @@ -30,7 +30,8 @@ #include "Visitor.h" -namespace MeshCore { +namespace MeshCore +{ /** * The MeshEvaluation class checks the mesh kernel for correctness with respect to a @@ -44,18 +45,20 @@ namespace MeshCore { class MeshExport MeshEvaluation { public: - explicit MeshEvaluation (const MeshKernel &rclB) : _rclMesh(rclB) {} - virtual ~MeshEvaluation () = default; + explicit MeshEvaluation(const MeshKernel& rclB) + : _rclMesh(rclB) + {} + virtual ~MeshEvaluation() = default; - /** - * Evaluates the mesh kernel with respect to certain criteria. Must be reimplemented by every - * subclass. This pure virtual function returns false if the mesh kernel is invalid according - * to this criterion and true if the mesh kernel is correct. - */ - virtual bool Evaluate () = 0; + /** + * Evaluates the mesh kernel with respect to certain criteria. Must be reimplemented by every + * subclass. This pure virtual function returns false if the mesh kernel is invalid according + * to this criterion and true if the mesh kernel is correct. + */ + virtual bool Evaluate() = 0; protected: - const MeshKernel& _rclMesh; /**< Mesh kernel */ + const MeshKernel& _rclMesh; /**< Mesh kernel */ }; // ---------------------------------------------------- @@ -70,17 +73,19 @@ protected: class MeshExport MeshValidation { public: - explicit MeshValidation (MeshKernel &rclB) : _rclMesh(rclB) {} - virtual ~MeshValidation () = default; + explicit MeshValidation(MeshKernel& rclB) + : _rclMesh(rclB) + {} + virtual ~MeshValidation() = default; - /** - * This function attempts to change the mesh kernel to be valid according to the checked - * criterion: True is returned if the errors could be fixed, false otherwise. - */ - virtual bool Fixup() = 0; + /** + * This function attempts to change the mesh kernel to be valid according to the checked + * criterion: True is returned if the errors could be fixed, false otherwise. + */ + virtual bool Fixup() = 0; protected: - MeshKernel& _rclMesh; /**< Mesh kernel */ + MeshKernel& _rclMesh; /**< Mesh kernel */ }; // ---------------------------------------------------- @@ -89,17 +94,17 @@ protected: * This class searches for nonuniform orientation of neighboured facets. * @author Werner Mayer */ -class MeshExport MeshOrientationVisitor : public MeshFacetVisitor +class MeshExport MeshOrientationVisitor: public MeshFacetVisitor { public: MeshOrientationVisitor(); /** Returns false after the first inconsistence is found, true otherwise. */ - bool Visit (const MeshFacet &, const MeshFacet &, FacetIndex , unsigned long ) override; + bool Visit(const MeshFacet&, const MeshFacet&, FacetIndex, unsigned long) override; bool HasNonUnifomOrientedFacets() const; private: - bool _nonuniformOrientation{false}; + bool _nonuniformOrientation {false}; }; /** @@ -107,14 +112,14 @@ private: * Note: The 'TMP0' flag for facets must be reset before using this class. * @author Werner Mayer */ -class MeshExport MeshOrientationCollector : public MeshOrientationVisitor +class MeshExport MeshOrientationCollector: public MeshOrientationVisitor { public: MeshOrientationCollector(std::vector& aulIndices, std::vector& aulComplement); /** Returns always true and collects the indices with wrong orientation. */ - bool Visit (const MeshFacet &, const MeshFacet &, FacetIndex , unsigned long) override; + bool Visit(const MeshFacet&, const MeshFacet&, FacetIndex, unsigned long) override; private: std::vector& _aulIndices; @@ -124,12 +129,12 @@ private: /** * @author Werner Mayer */ -class MeshExport MeshSameOrientationCollector : public MeshOrientationVisitor +class MeshExport MeshSameOrientationCollector: public MeshOrientationVisitor { public: explicit MeshSameOrientationCollector(std::vector& aulIndices); /** Returns always true and collects the indices with wrong orientation. */ - bool Visit (const MeshFacet &, const MeshFacet &, FacetIndex , unsigned long) override; + bool Visit(const MeshFacet&, const MeshFacet&, FacetIndex, unsigned long) override; private: std::vector& _aulIndices; @@ -139,11 +144,11 @@ private: * The MeshEvalOrientation class checks the mesh kernel for consistent facet normals. * @author Werner Mayer */ -class MeshExport MeshEvalOrientation : public MeshEvaluation +class MeshExport MeshEvalOrientation: public MeshEvaluation { public: - explicit MeshEvalOrientation (const MeshKernel& rclM); - bool Evaluate () override; + explicit MeshEvalOrientation(const MeshKernel& rclM); + bool Evaluate() override; std::vector GetIndices() const; private: @@ -154,10 +159,10 @@ private: * The MeshFixOrientation class harmonizes the facet normals of the passed mesh kernel. * @author Werner Mayer */ -class MeshExport MeshFixOrientation : public MeshValidation +class MeshExport MeshFixOrientation: public MeshValidation { public: - explicit MeshFixOrientation (MeshKernel& rclM); + explicit MeshFixOrientation(MeshKernel& rclM); bool Fixup() override; }; @@ -167,11 +172,11 @@ public: * The MeshEvalSolid class checks if the mesh represents a solid. * @author Werner Mayer */ -class MeshExport MeshEvalSolid : public MeshEvaluation +class MeshExport MeshEvalSolid: public MeshEvaluation { public: - explicit MeshEvalSolid (const MeshKernel& rclM); - bool Evaluate () override; + explicit MeshEvalSolid(const MeshKernel& rclM); + bool Evaluate() override; }; // ---------------------------------------------------- @@ -182,38 +187,51 @@ public: * non-manifold if it is shared by more than two facets. * @note This check does not necessarily cover any degenerations. */ -class MeshExport MeshEvalTopology : public MeshEvaluation +class MeshExport MeshEvalTopology: public MeshEvaluation { public: - explicit MeshEvalTopology (const MeshKernel &rclB) : MeshEvaluation(rclB) {} - bool Evaluate () override; + explicit MeshEvalTopology(const MeshKernel& rclB) + : MeshEvaluation(rclB) + {} + bool Evaluate() override; - void GetFacetManifolds (std::vector &raclFacetIndList) const; + void GetFacetManifolds(std::vector& raclFacetIndList) const; unsigned long CountManifolds() const; - const std::vector >& GetIndices() const { return nonManifoldList; } - const std::list >& GetFacets() const { return nonManifoldFacets; } + const std::vector>& GetIndices() const + { + return nonManifoldList; + } + const std::list>& GetFacets() const + { + return nonManifoldFacets; + } protected: - std::vector > nonManifoldList; - std::list > nonManifoldFacets; + std::vector> nonManifoldList; + std::list> nonManifoldFacets; }; /** * The MeshFixTopology class tries to fix a few cases of non-manifolds. * @see MeshEvalTopology */ -class MeshExport MeshFixTopology : public MeshValidation +class MeshExport MeshFixTopology: public MeshValidation { public: - MeshFixTopology (MeshKernel &rclB, const std::list >& mf) - : MeshValidation(rclB), nonManifoldList(mf) {} + MeshFixTopology(MeshKernel& rclB, const std::list>& mf) + : MeshValidation(rclB) + , nonManifoldList(mf) + {} bool Fixup() override; - const std::vector& GetDeletedFaces() const { return deletedFaces; } + const std::vector& GetDeletedFaces() const + { + return deletedFaces; + } protected: std::vector deletedFaces; - const std::list >& nonManifoldList; + const std::list>& nonManifoldList; }; // ---------------------------------------------------- @@ -224,20 +242,31 @@ protected: * the point but are not topologically connected over a common edge. * Such mesh defects can lead to some very ugly folds on the surface. */ -class MeshExport MeshEvalPointManifolds : public MeshEvaluation +class MeshExport MeshEvalPointManifolds: public MeshEvaluation { public: - explicit MeshEvalPointManifolds (const MeshKernel &rclB) : MeshEvaluation(rclB) {} - bool Evaluate () override; + explicit MeshEvalPointManifolds(const MeshKernel& rclB) + : MeshEvaluation(rclB) + {} + bool Evaluate() override; - void GetFacetIndices (std::vector &facets) const; - const std::list >& GetFacetIndices () const { return facetsOfNonManifoldPoints; } - const std::vector& GetIndices() const { return nonManifoldPoints; } - unsigned long CountManifolds() const { return static_cast(nonManifoldPoints.size()); } + void GetFacetIndices(std::vector& facets) const; + const std::list>& GetFacetIndices() const + { + return facetsOfNonManifoldPoints; + } + const std::vector& GetIndices() const + { + return nonManifoldPoints; + } + unsigned long CountManifolds() const + { + return static_cast(nonManifoldPoints.size()); + } protected: std::vector nonManifoldPoints; - std::list > facetsOfNonManifoldPoints; + std::list> facetsOfNonManifoldPoints; }; // ---------------------------------------------------- @@ -249,26 +278,30 @@ protected: * at their other edges. * Such facets can just be removed from the mesh. */ -class MeshExport MeshEvalSingleFacet : public MeshEvalTopology +class MeshExport MeshEvalSingleFacet: public MeshEvalTopology { public: - explicit MeshEvalSingleFacet (const MeshKernel &rclB) : MeshEvalTopology(rclB) {} - bool Evaluate () override; + explicit MeshEvalSingleFacet(const MeshKernel& rclB) + : MeshEvalTopology(rclB) + {} + bool Evaluate() override; }; /** * The MeshFixSingleFacet class tries to fix a special case of non-manifolds. * @see MeshEvalSingleFacet */ -class MeshExport MeshFixSingleFacet : public MeshValidation +class MeshExport MeshFixSingleFacet: public MeshValidation { public: - MeshFixSingleFacet (MeshKernel &rclB, const std::vector >& mf) - : MeshValidation(rclB), _raclManifoldList(mf) {} - bool Fixup() override; + MeshFixSingleFacet(MeshKernel& rclB, const std::vector>& mf) + : MeshValidation(rclB) + , _raclManifoldList(mf) + {} + bool Fixup() override; protected: - const std::vector >& _raclManifoldList; + const std::vector>& _raclManifoldList; }; // ---------------------------------------------------- @@ -277,33 +310,38 @@ protected: * The MeshEvalSelfIntersection class checks the mesh for self intersection. * @author Werner Mayer */ -class MeshExport MeshEvalSelfIntersection : public MeshEvaluation +class MeshExport MeshEvalSelfIntersection: public MeshEvaluation { public: - explicit MeshEvalSelfIntersection (const MeshKernel &rclB) : MeshEvaluation(rclB) {} + explicit MeshEvalSelfIntersection(const MeshKernel& rclB) + : MeshEvaluation(rclB) + {} /// Evaluate the mesh and return if true if there are self intersections - bool Evaluate () override; + bool Evaluate() override; /// collect all intersection lines - void GetIntersections(const std::vector >&, - std::vector >&) const; + void GetIntersections(const std::vector>&, + std::vector>&) const; /// collect the index of all facets with self intersections - void GetIntersections(std::vector >&) const; + void GetIntersections(std::vector>&) const; }; /** * The MeshFixSelfIntersection class tries to fix self-intersections. * @see MeshEvalSingleFacet */ -class MeshExport MeshFixSelfIntersection : public MeshValidation +class MeshExport MeshFixSelfIntersection: public MeshValidation { public: - MeshFixSelfIntersection (MeshKernel &rclB, const std::vector >& si) - : MeshValidation(rclB), selfIntersectons(si) {} + MeshFixSelfIntersection(MeshKernel& rclB, + const std::vector>& si) + : MeshValidation(rclB) + , selfIntersectons(si) + {} std::vector GetFacets() const; bool Fixup() override; private: - const std::vector >& selfIntersectons; + const std::vector>& selfIntersectons; }; // ---------------------------------------------------- @@ -313,23 +351,27 @@ private: * set correctly. * @author Werner Mayer */ -class MeshExport MeshEvalNeighbourhood : public MeshEvaluation +class MeshExport MeshEvalNeighbourhood: public MeshEvaluation { public: - explicit MeshEvalNeighbourhood (const MeshKernel &rclB) : MeshEvaluation(rclB) {} - bool Evaluate () override; - std::vector GetIndices() const; + explicit MeshEvalNeighbourhood(const MeshKernel& rclB) + : MeshEvaluation(rclB) + {} + bool Evaluate() override; + std::vector GetIndices() const; }; /** * The MeshFixNeighbourhood class fixes the neighbourhood of the facets. * @author Werner Mayer */ -class MeshExport MeshFixNeighbourhood : public MeshValidation +class MeshExport MeshFixNeighbourhood: public MeshValidation { public: - explicit MeshFixNeighbourhood (MeshKernel &rclB) : MeshValidation(rclB) {} - bool Fixup() override; + explicit MeshFixNeighbourhood(MeshKernel& rclB) + : MeshValidation(rclB) + {} + bool Fixup() override; }; // ---------------------------------------------------- @@ -342,31 +384,32 @@ public: * expansion. The local coordinate system is right-handed. * @author Werner Mayer */ -class MeshExport MeshEigensystem : public MeshEvaluation +class MeshExport MeshEigensystem: public MeshEvaluation { public: - explicit MeshEigensystem (const MeshKernel &rclB); + explicit MeshEigensystem(const MeshKernel& rclB); - /** Returns the transformation matrix. */ - Base::Matrix4D Transform() const; - /** - * Returns the expansions in \a u, \a v and \a w of the bounding box. - */ - Base::Vector3f GetBoundings() const; + /** Returns the transformation matrix. */ + Base::Matrix4D Transform() const; + /** + * Returns the expansions in \a u, \a v and \a w of the bounding box. + */ + Base::Vector3f GetBoundings() const; - bool Evaluate() override; - /** - * Calculates the local coordinate system defined by \a u, \a v, \a w - * and \a c. - */ + bool Evaluate() override; + /** + * Calculates the local coordinate system defined by \a u, \a v, \a w + * and \a c. + */ protected: - void CalculateLocalSystem(); + void CalculateLocalSystem(); private: - Base::Vector3f _cU, _cV, _cW, _cC; /**< Vectors that define the local coordinate system. */ - float _fU, _fV, _fW; /**< Expansion in \a u, \a v, and \a w direction of the transformed mesh. */ + Base::Vector3f _cU, _cV, _cW, _cC; /**< Vectors that define the local coordinate system. */ + float _fU, _fV, + _fW; /**< Expansion in \a u, \a v, and \a w direction of the transformed mesh. */ }; -} // namespace MeshCore +} // namespace MeshCore -#endif // MESH_EVALUATION_H +#endif // MESH_EVALUATION_H diff --git a/src/Mod/Mesh/App/Core/Functional.h b/src/Mod/Mesh/App/Core/Functional.h index cf71a8dd09..d33a1cdda6 100644 --- a/src/Mod/Mesh/App/Core/Functional.h +++ b/src/Mod/Mesh/App/Core/Functional.h @@ -23,41 +23,40 @@ #ifndef MESH_FUNCTIONAL_H #define MESH_FUNCTIONAL_H -#include -#include #include +#include +#include namespace MeshCore { - template - static void parallel_sort(Iter begin, Iter end, Pred comp, int threads) - { - if (threads < 2 || end - begin < 2) - { - std::sort(begin, end, comp); - } - else - { - Iter mid = begin + (end - begin) / 2; - if (threads == 2) - { - QFuture future = QtConcurrent::run(parallel_sort, begin, mid, comp, threads / 2); - std::sort(mid, end, comp); - future.waitForFinished(); - } - else - { - QFuture a = QtConcurrent::run(parallel_sort, begin, mid, comp, threads / 2); - QFuture b = QtConcurrent::run(parallel_sort, mid, end, comp, threads / 2); - a.waitForFinished(); - b.waitForFinished(); - } - std::inplace_merge(begin, mid, end, comp); - } +template +static void parallel_sort(Iter begin, Iter end, Pred comp, int threads) +{ + if (threads < 2 || end - begin < 2) { + std::sort(begin, end, comp); } + else { + Iter mid = begin + (end - begin) / 2; + if (threads == 2) { + QFuture future = + QtConcurrent::run(parallel_sort, begin, mid, comp, threads / 2); + std::sort(mid, end, comp); + future.waitForFinished(); + } + else { + QFuture a = + QtConcurrent::run(parallel_sort, begin, mid, comp, threads / 2); + QFuture b = + QtConcurrent::run(parallel_sort, mid, end, comp, threads / 2); + a.waitForFinished(); + b.waitForFinished(); + } + std::inplace_merge(begin, mid, end, comp); + } +} -} // namespace MeshCore +} // namespace MeshCore #endif // MESH_FUNCTIONAL_H diff --git a/src/Mod/Mesh/App/Core/Grid.cpp b/src/Mod/Mesh/App/Core/Grid.cpp index 1a4dc27db0..0ad39efa4e 100644 --- a/src/Mod/Mesh/App/Core/Grid.cpp +++ b/src/Mod/Mesh/App/Core/Grid.cpp @@ -23,241 +23,272 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif -#include "Grid.h" #include "Algorithm.h" +#include "Grid.h" #include "Iterator.h" #include "MeshKernel.h" using namespace MeshCore; -MeshGrid::MeshGrid (const MeshKernel &rclM) -: _pclMesh(&rclM), - _ulCtElements(0), - _ulCtGridsX(0), _ulCtGridsY(0), _ulCtGridsZ(0), - _fGridLenX(0.0f), _fGridLenY(0.0f), _fGridLenZ(0.0f), - _fMinX(0.0f), _fMinY(0.0f), _fMinZ(0.0f) +MeshGrid::MeshGrid(const MeshKernel& rclM) + : _pclMesh(&rclM) + , _ulCtElements(0) + , _ulCtGridsX(0) + , _ulCtGridsY(0) + , _ulCtGridsZ(0) + , _fGridLenX(0.0f) + , _fGridLenY(0.0f) + , _fGridLenZ(0.0f) + , _fMinX(0.0f) + , _fMinY(0.0f) + , _fMinZ(0.0f) +{} + +MeshGrid::MeshGrid() + : _pclMesh(nullptr) + , _ulCtElements(0) + , _ulCtGridsX(MESH_CT_GRID) + , _ulCtGridsY(MESH_CT_GRID) + , _ulCtGridsZ(MESH_CT_GRID) + , _fGridLenX(0.0f) + , _fGridLenY(0.0f) + , _fGridLenZ(0.0f) + , _fMinX(0.0f) + , _fMinY(0.0f) + , _fMinZ(0.0f) +{} + +void MeshGrid::Attach(const MeshKernel& rclM) { + _pclMesh = &rclM; + RebuildGrid(); } -MeshGrid::MeshGrid () -: _pclMesh(nullptr), - _ulCtElements(0), - _ulCtGridsX(MESH_CT_GRID), _ulCtGridsY(MESH_CT_GRID), _ulCtGridsZ(MESH_CT_GRID), - _fGridLenX(0.0f), _fGridLenY(0.0f), _fGridLenZ(0.0f), - _fMinX(0.0f), _fMinY(0.0f), _fMinZ(0.0f) +void MeshGrid::Clear() { + _aulGrid.clear(); + _pclMesh = nullptr; } -void MeshGrid::Attach (const MeshKernel &rclM) +void MeshGrid::Rebuild(unsigned long ulX, unsigned long ulY, unsigned long ulZ) { - _pclMesh = &rclM; - RebuildGrid(); + _ulCtGridsX = ulX; + _ulCtGridsY = ulY; + _ulCtGridsZ = ulZ; + _ulCtElements = HasElements(); + RebuildGrid(); } -void MeshGrid::Clear () +void MeshGrid::Rebuild(unsigned long ulPerGrid, unsigned long ulMaxGrid) { - _aulGrid.clear(); - _pclMesh = nullptr; + _ulCtElements = HasElements(); + CalculateGridLength(ulPerGrid, ulMaxGrid); + RebuildGrid(); } -void MeshGrid::Rebuild (unsigned long ulX, unsigned long ulY, unsigned long ulZ) +void MeshGrid::Rebuild(int iCtGridPerAxis) { - _ulCtGridsX = ulX; - _ulCtGridsY = ulY; - _ulCtGridsZ = ulZ; - _ulCtElements = HasElements(); - RebuildGrid(); + _ulCtElements = HasElements(); + CalculateGridLength(iCtGridPerAxis); + RebuildGrid(); } -void MeshGrid::Rebuild (unsigned long ulPerGrid, unsigned long ulMaxGrid) +void MeshGrid::InitGrid() { - _ulCtElements = HasElements(); - CalculateGridLength(ulPerGrid, ulMaxGrid); - RebuildGrid(); -} + assert(_pclMesh); -void MeshGrid::Rebuild (int iCtGridPerAxis) -{ - _ulCtElements = HasElements(); - CalculateGridLength(iCtGridPerAxis); - RebuildGrid(); -} + unsigned long i, j; -void MeshGrid::InitGrid () -{ - assert(_pclMesh); - - unsigned long i, j; - - // Calculate grid length if not initialised - // - if ((_ulCtGridsX == 0) || (_ulCtGridsY == 0) || (_ulCtGridsZ == 0)) - CalculateGridLength(MESH_CT_GRID, MESH_MAX_GRIDS); - - // Determine grid length and offset - // - { - Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox(); - - float fLengthX = clBBMesh.LengthX(); - float fLengthY = clBBMesh.LengthY(); - float fLengthZ = clBBMesh.LengthZ(); - - { - // Offset fGridLen/2 + // Calculate grid length if not initialised // - _fGridLenX = (1.0f + fLengthX) / float(_ulCtGridsX); - _fMinX = clBBMesh.MinX - 0.5f; - } - - { - _fGridLenY = (1.0f + fLengthY) / float(_ulCtGridsY); - _fMinY = clBBMesh.MinY - 0.5f; - } - - { - _fGridLenZ = (1.0f + fLengthZ) / float(_ulCtGridsZ); - _fMinZ = clBBMesh.MinZ - 0.5f; - } - } - - // Create data structure - _aulGrid.clear(); - _aulGrid.resize(_ulCtGridsX); - for (i = 0; i < _ulCtGridsX; i++) - { - _aulGrid[i].resize(_ulCtGridsY); - for (j = 0; j < _ulCtGridsY; j++) - _aulGrid[i][j].resize(_ulCtGridsZ); - } -} - -unsigned long MeshGrid::Inside (const Base::BoundBox3f &rclBB, std::vector &raulElements, - bool bDelDoubles) const -{ - unsigned long i, j, k, ulMinX, ulMinY, ulMinZ, ulMaxX, ulMaxY, ulMaxZ; - - raulElements.clear(); - - // Grid boxes for a more detailed selection - Position(Base::Vector3f(rclBB.MinX, rclBB.MinY, rclBB.MinZ), ulMinX, ulMinY, ulMinZ); - Position(Base::Vector3f(rclBB.MaxX, rclBB.MaxY, rclBB.MaxZ), ulMaxX, ulMaxY, ulMaxZ); - - for (i = ulMinX; i <= ulMaxX; i++) - { - for (j = ulMinY; j <= ulMaxY; j++) - { - for (k = ulMinZ; k <= ulMaxZ; k++) - { - raulElements.insert(raulElements.end(), _aulGrid[i][j][k].begin(), _aulGrid[i][j][k].end()); - } + if ((_ulCtGridsX == 0) || (_ulCtGridsY == 0) || (_ulCtGridsZ == 0)) { + CalculateGridLength(MESH_CT_GRID, MESH_MAX_GRIDS); } - } - if (bDelDoubles) - { - // remove duplicate mentions - std::sort(raulElements.begin(), raulElements.end()); - raulElements.erase(std::unique(raulElements.begin(), raulElements.end()), raulElements.end()); - } - - return raulElements.size(); -} - -unsigned long MeshGrid::Inside (const Base::BoundBox3f &rclBB, std::vector &raulElements, - const Base::Vector3f &rclOrg, float fMaxDist, bool bDelDoubles) const -{ - unsigned long i, j, k, ulMinX, ulMinY, ulMinZ, ulMaxX, ulMaxY, ulMaxZ; - float fGridDiag = GetBoundBox(0, 0, 0).CalcDiagonalLength(); - float fMinDistP2 = (fGridDiag * fGridDiag) + (fMaxDist * fMaxDist); - - raulElements.clear(); - - // Grid boxes for a more detailed selection - Position(Base::Vector3f(rclBB.MinX, rclBB.MinY, rclBB.MinZ), ulMinX, ulMinY, ulMinZ); - Position(Base::Vector3f(rclBB.MaxX, rclBB.MaxY, rclBB.MaxZ), ulMaxX, ulMaxY, ulMaxZ); - - for (i = ulMinX; i <= ulMaxX; i++) - { - for (j = ulMinY; j <= ulMaxY; j++) + // Determine grid length and offset + // { - for (k = ulMinZ; k <= ulMaxZ; k++) - { - if (Base::DistanceP2(GetBoundBox(i, j, k).GetCenter(), rclOrg) < fMinDistP2) - raulElements.insert(raulElements.end(), _aulGrid[i][j][k].begin(), _aulGrid[i][j][k].end()); - } + Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox(); + + float fLengthX = clBBMesh.LengthX(); + float fLengthY = clBBMesh.LengthY(); + float fLengthZ = clBBMesh.LengthZ(); + + { + // Offset fGridLen/2 + // + _fGridLenX = (1.0f + fLengthX) / float(_ulCtGridsX); + _fMinX = clBBMesh.MinX - 0.5f; + } + + { + _fGridLenY = (1.0f + fLengthY) / float(_ulCtGridsY); + _fMinY = clBBMesh.MinY - 0.5f; + } + + { + _fGridLenZ = (1.0f + fLengthZ) / float(_ulCtGridsZ); + _fMinZ = clBBMesh.MinZ - 0.5f; + } } - } - if (bDelDoubles) - { - // remove duplicate mentions - std::sort(raulElements.begin(), raulElements.end()); - raulElements.erase(std::unique(raulElements.begin(), raulElements.end()), raulElements.end()); - } - - return raulElements.size(); -} - -unsigned long MeshGrid::Inside (const Base::BoundBox3f &rclBB, std::set &raulElements) const -{ - unsigned long i, j, k, ulMinX, ulMinY, ulMinZ, ulMaxX, ulMaxY, ulMaxZ; - - raulElements.clear(); - - // Grid boxes for a more detailed selection - Position(Base::Vector3f(rclBB.MinX, rclBB.MinY, rclBB.MinZ), ulMinX, ulMinY, ulMinZ); - Position(Base::Vector3f(rclBB.MaxX, rclBB.MaxY, rclBB.MaxZ), ulMaxX, ulMaxY, ulMaxZ); - - for (i = ulMinX; i <= ulMaxX; i++) - { - for (j = ulMinY; j <= ulMaxY; j++) - { - for (k = ulMinZ; k <= ulMaxZ; k++) - { - raulElements.insert(_aulGrid[i][j][k].begin(), _aulGrid[i][j][k].end()); - } + // Create data structure + _aulGrid.clear(); + _aulGrid.resize(_ulCtGridsX); + for (i = 0; i < _ulCtGridsX; i++) { + _aulGrid[i].resize(_ulCtGridsY); + for (j = 0; j < _ulCtGridsY; j++) { + _aulGrid[i][j].resize(_ulCtGridsZ); + } } - } - - return raulElements.size(); } -bool MeshGrid::CheckPosition (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const +unsigned long MeshGrid::Inside(const Base::BoundBox3f& rclBB, + std::vector& raulElements, + bool bDelDoubles) const { - rulX = static_cast((rclPoint.x - _fMinX) / _fGridLenX); - rulY = static_cast((rclPoint.y - _fMinY) / _fGridLenY); - rulZ = static_cast((rclPoint.z - _fMinZ) / _fGridLenZ); + unsigned long i, j, k, ulMinX, ulMinY, ulMinZ, ulMaxX, ulMaxY, ulMaxZ; - if ( (rulX < _ulCtGridsX) && (rulY < _ulCtGridsY) && (rulZ < _ulCtGridsZ) ) - return true; + raulElements.clear(); - return false; + // Grid boxes for a more detailed selection + Position(Base::Vector3f(rclBB.MinX, rclBB.MinY, rclBB.MinZ), ulMinX, ulMinY, ulMinZ); + Position(Base::Vector3f(rclBB.MaxX, rclBB.MaxY, rclBB.MaxZ), ulMaxX, ulMaxY, ulMaxZ); + + for (i = ulMinX; i <= ulMaxX; i++) { + for (j = ulMinY; j <= ulMaxY; j++) { + for (k = ulMinZ; k <= ulMaxZ; k++) { + raulElements.insert(raulElements.end(), + _aulGrid[i][j][k].begin(), + _aulGrid[i][j][k].end()); + } + } + } + + if (bDelDoubles) { + // remove duplicate mentions + std::sort(raulElements.begin(), raulElements.end()); + raulElements.erase(std::unique(raulElements.begin(), raulElements.end()), + raulElements.end()); + } + + return raulElements.size(); } -void MeshGrid::Position (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const +unsigned long MeshGrid::Inside(const Base::BoundBox3f& rclBB, + std::vector& raulElements, + const Base::Vector3f& rclOrg, + float fMaxDist, + bool bDelDoubles) const { - if (rclPoint.x <= _fMinX) - rulX = 0; - else - rulX = std::min(static_cast((rclPoint.x - _fMinX) / _fGridLenX), _ulCtGridsX - 1); + unsigned long i, j, k, ulMinX, ulMinY, ulMinZ, ulMaxX, ulMaxY, ulMaxZ; + float fGridDiag = GetBoundBox(0, 0, 0).CalcDiagonalLength(); + float fMinDistP2 = (fGridDiag * fGridDiag) + (fMaxDist * fMaxDist); - if (rclPoint.y <= _fMinY) - rulY = 0; - else - rulY = std::min(static_cast((rclPoint.y - _fMinY) / _fGridLenY), _ulCtGridsY - 1); + raulElements.clear(); - if (rclPoint.z <= _fMinZ) - rulZ = 0; - else - rulZ = std::min(static_cast((rclPoint.z - _fMinZ) / _fGridLenZ), _ulCtGridsZ - 1); + // Grid boxes for a more detailed selection + Position(Base::Vector3f(rclBB.MinX, rclBB.MinY, rclBB.MinZ), ulMinX, ulMinY, ulMinZ); + Position(Base::Vector3f(rclBB.MaxX, rclBB.MaxY, rclBB.MaxZ), ulMaxX, ulMaxY, ulMaxZ); + + for (i = ulMinX; i <= ulMaxX; i++) { + for (j = ulMinY; j <= ulMaxY; j++) { + for (k = ulMinZ; k <= ulMaxZ; k++) { + if (Base::DistanceP2(GetBoundBox(i, j, k).GetCenter(), rclOrg) < fMinDistP2) { + raulElements.insert(raulElements.end(), + _aulGrid[i][j][k].begin(), + _aulGrid[i][j][k].end()); + } + } + } + } + + if (bDelDoubles) { + // remove duplicate mentions + std::sort(raulElements.begin(), raulElements.end()); + raulElements.erase(std::unique(raulElements.begin(), raulElements.end()), + raulElements.end()); + } + + return raulElements.size(); } -void MeshGrid::CalculateGridLength (unsigned long ulCtGrid, unsigned long ulMaxGrids) +unsigned long MeshGrid::Inside(const Base::BoundBox3f& rclBB, + std::set& raulElements) const +{ + unsigned long i, j, k, ulMinX, ulMinY, ulMinZ, ulMaxX, ulMaxY, ulMaxZ; + + raulElements.clear(); + + // Grid boxes for a more detailed selection + Position(Base::Vector3f(rclBB.MinX, rclBB.MinY, rclBB.MinZ), ulMinX, ulMinY, ulMinZ); + Position(Base::Vector3f(rclBB.MaxX, rclBB.MaxY, rclBB.MaxZ), ulMaxX, ulMaxY, ulMaxZ); + + for (i = ulMinX; i <= ulMaxX; i++) { + for (j = ulMinY; j <= ulMaxY; j++) { + for (k = ulMinZ; k <= ulMaxZ; k++) { + raulElements.insert(_aulGrid[i][j][k].begin(), _aulGrid[i][j][k].end()); + } + } + } + + return raulElements.size(); +} + +bool MeshGrid::CheckPosition(const Base::Vector3f& rclPoint, + unsigned long& rulX, + unsigned long& rulY, + unsigned long& rulZ) const +{ + rulX = static_cast((rclPoint.x - _fMinX) / _fGridLenX); + rulY = static_cast((rclPoint.y - _fMinY) / _fGridLenY); + rulZ = static_cast((rclPoint.z - _fMinZ) / _fGridLenZ); + + if ((rulX < _ulCtGridsX) && (rulY < _ulCtGridsY) && (rulZ < _ulCtGridsZ)) { + return true; + } + + return false; +} + +void MeshGrid::Position(const Base::Vector3f& rclPoint, + unsigned long& rulX, + unsigned long& rulY, + unsigned long& rulZ) const +{ + if (rclPoint.x <= _fMinX) { + rulX = 0; + } + else { + rulX = + std::min(static_cast((rclPoint.x - _fMinX) / _fGridLenX), + _ulCtGridsX - 1); + } + + if (rclPoint.y <= _fMinY) { + rulY = 0; + } + else { + rulY = + std::min(static_cast((rclPoint.y - _fMinY) / _fGridLenY), + _ulCtGridsY - 1); + } + + if (rclPoint.z <= _fMinZ) { + rulZ = 0; + } + else { + rulZ = + std::min(static_cast((rclPoint.z - _fMinZ) / _fGridLenZ), + _ulCtGridsZ - 1); + } +} + +void MeshGrid::CalculateGridLength(unsigned long ulCtGrid, unsigned long ulMaxGrids) { // Calculate grid lengths or number of grids per dimension // There should be about 10 (?!?!) facets per grid @@ -272,10 +303,12 @@ void MeshGrid::CalculateGridLength (unsigned long ulCtGrid, unsigned long ulMaxG float fVolume = fLenX * fLenY * fLenZ; if (fVolume > 0.0f) { float fVolElem; - if (_ulCtElements > (ulMaxGrids * ulCtGrid)) + if (_ulCtElements > (ulMaxGrids * ulCtGrid)) { fVolElem = (fLenX * fLenY * fLenZ) / float(ulMaxGrids * ulCtGrid); - else + } + else { fVolElem = (fLenX * fLenY * fLenZ) / float(_ulCtElements); + } float fVol = fVolElem * float(ulCtGrid); fGridLen = float(pow(fVol, 1.0f / 3.0f)); @@ -284,10 +317,12 @@ void MeshGrid::CalculateGridLength (unsigned long ulCtGrid, unsigned long ulMaxG // Planar bounding box float fArea = fLenX * fLenY + fLenX * fLenZ + fLenY * fLenZ; float fAreaElem; - if (_ulCtElements > (ulMaxGrids * ulCtGrid)) + if (_ulCtElements > (ulMaxGrids * ulCtGrid)) { fAreaElem = fArea / float(ulMaxGrids * ulCtGrid); - else + } + else { fAreaElem = fArea / float(_ulCtElements); + } float fRepresentativeArea = fAreaElem * static_cast(ulCtGrid); fGridLen = sqrt(fRepresentativeArea); @@ -306,942 +341,975 @@ void MeshGrid::CalculateGridLength (unsigned long ulCtGrid, unsigned long ulMaxG } } -void MeshGrid::CalculateGridLength (int iCtGridPerAxis) +void MeshGrid::CalculateGridLength(int iCtGridPerAxis) { - if (iCtGridPerAxis<=0) - { - CalculateGridLength(MESH_CT_GRID, MESH_MAX_GRIDS); - return; - } + if (iCtGridPerAxis <= 0) { + CalculateGridLength(MESH_CT_GRID, MESH_MAX_GRIDS); + return; + } - // Calculate grid lengths or number of grids per dimension - // There should be about 10 (?!?!) facets per grid - // respectively max grids should not exceed 10000 - Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox(); + // Calculate grid lengths or number of grids per dimension + // There should be about 10 (?!?!) facets per grid + // respectively max grids should not exceed 10000 + Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox(); - float fLenghtX = clBBMesh.LengthX(); - float fLenghtY = clBBMesh.LengthY(); - float fLenghtZ = clBBMesh.LengthZ(); + float fLenghtX = clBBMesh.LengthX(); + float fLenghtY = clBBMesh.LengthY(); + float fLenghtZ = clBBMesh.LengthZ(); - float fLenghtD = clBBMesh.CalcDiagonalLength(); + float fLenghtD = clBBMesh.CalcDiagonalLength(); - float fLengthTol = 0.05f * fLenghtD; + float fLengthTol = 0.05f * fLenghtD; - bool bLenghtXisZero = (fLenghtX <= fLengthTol); - bool bLenghtYisZero = (fLenghtY <= fLengthTol); - bool bLenghtZisZero = (fLenghtZ <= fLengthTol); + bool bLenghtXisZero = (fLenghtX <= fLengthTol); + bool bLenghtYisZero = (fLenghtY <= fLengthTol); + bool bLenghtZisZero = (fLenghtZ <= fLengthTol); - int iFlag = 0; + int iFlag = 0; - int iMaxGrids = 1; + int iMaxGrids = 1; - if (bLenghtXisZero) - iFlag += 1; - else - iMaxGrids *= iCtGridPerAxis; + if (bLenghtXisZero) { + iFlag += 1; + } + else { + iMaxGrids *= iCtGridPerAxis; + } - if (bLenghtYisZero) - iFlag += 2; - else - iMaxGrids *= iCtGridPerAxis; + if (bLenghtYisZero) { + iFlag += 2; + } + else { + iMaxGrids *= iCtGridPerAxis; + } - if (bLenghtZisZero) - iFlag += 4; - else - iMaxGrids *= iCtGridPerAxis; + if (bLenghtZisZero) { + iFlag += 4; + } + else { + iMaxGrids *= iCtGridPerAxis; + } - unsigned long ulGridsFacets = 10; + unsigned long ulGridsFacets = 10; - float fFactorVolumen = 40.0; - float fFactorArea = 10.0; + float fFactorVolumen = 40.0; + float fFactorArea = 10.0; - switch (iFlag) - { - case 0: - { - float fVolumen = fLenghtX * fLenghtY * fLenghtZ; + switch (iFlag) { + case 0: { + float fVolumen = fLenghtX * fLenghtY * fLenghtZ; - float fVolumenGrid = (fVolumen * ulGridsFacets) / (fFactorVolumen * _ulCtElements); + float fVolumenGrid = (fVolumen * ulGridsFacets) / (fFactorVolumen * _ulCtElements); - if ((fVolumenGrid * iMaxGrids) < fVolumen) - fVolumenGrid = fVolumen / static_cast(iMaxGrids); + if ((fVolumenGrid * iMaxGrids) < fVolumen) { + fVolumenGrid = fVolumen / static_cast(iMaxGrids); + } - float fLengthGrid = pow(fVolumenGrid, 1.0f / 3.0f); + float fLengthGrid = pow(fVolumenGrid, 1.0f / 3.0f); - _ulCtGridsX = std::max(static_cast(fLenghtX / fLengthGrid), 1); - _ulCtGridsY = std::max(static_cast(fLenghtY / fLengthGrid), 1); - _ulCtGridsZ = std::max(static_cast(fLenghtZ / fLengthGrid), 1); + _ulCtGridsX = + std::max(static_cast(fLenghtX / fLengthGrid), 1); + _ulCtGridsY = + std::max(static_cast(fLenghtY / fLengthGrid), 1); + _ulCtGridsZ = + std::max(static_cast(fLenghtZ / fLengthGrid), 1); - } break; - case 1: - { - _ulCtGridsX = 1; // bLenghtXisZero + } break; + case 1: { + _ulCtGridsX = 1; // bLenghtXisZero - float fArea = fLenghtY * fLenghtZ; + float fArea = fLenghtY * fLenghtZ; - float fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements); + float fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements); - if ((fAreaGrid * iMaxGrids) < fArea) - fAreaGrid = fArea / static_cast(iMaxGrids); + if ((fAreaGrid * iMaxGrids) < fArea) { + fAreaGrid = fArea / static_cast(iMaxGrids); + } - float fLengthGrid = float(sqrt(fAreaGrid)); + float fLengthGrid = float(sqrt(fAreaGrid)); - _ulCtGridsY = std::max(static_cast(fLenghtY / fLengthGrid), 1); - _ulCtGridsZ = std::max(static_cast(fLenghtZ / fLengthGrid), 1); - } break; - case 2: - { - _ulCtGridsY = 1; // bLenghtYisZero + _ulCtGridsY = + std::max(static_cast(fLenghtY / fLengthGrid), 1); + _ulCtGridsZ = + std::max(static_cast(fLenghtZ / fLengthGrid), 1); + } break; + case 2: { + _ulCtGridsY = 1; // bLenghtYisZero - float fArea = fLenghtX * fLenghtZ; + float fArea = fLenghtX * fLenghtZ; - float fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements); + float fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements); - if ((fAreaGrid * iMaxGrids) < fArea) - fAreaGrid = fArea / static_cast(iMaxGrids); + if ((fAreaGrid * iMaxGrids) < fArea) { + fAreaGrid = fArea / static_cast(iMaxGrids); + } - float fLengthGrid = float(sqrt(fAreaGrid)); + float fLengthGrid = float(sqrt(fAreaGrid)); - _ulCtGridsX = std::max(static_cast(fLenghtX / fLengthGrid), 1); - _ulCtGridsZ = std::max(static_cast(fLenghtZ / fLengthGrid), 1); - } break; - case 3: - { - _ulCtGridsX = 1; // bLenghtXisZero - _ulCtGridsY = 1; // bLenghtYisZero - _ulCtGridsZ = static_cast(iMaxGrids); // bLenghtYisZero - } break; - case 4: - { - _ulCtGridsZ = 1; // bLenghtZisZero + _ulCtGridsX = + std::max(static_cast(fLenghtX / fLengthGrid), 1); + _ulCtGridsZ = + std::max(static_cast(fLenghtZ / fLengthGrid), 1); + } break; + case 3: { + _ulCtGridsX = 1; // bLenghtXisZero + _ulCtGridsY = 1; // bLenghtYisZero + _ulCtGridsZ = static_cast(iMaxGrids); // bLenghtYisZero + } break; + case 4: { + _ulCtGridsZ = 1; // bLenghtZisZero - float fArea = fLenghtX * fLenghtY; + float fArea = fLenghtX * fLenghtY; - float fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements); + float fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements); - if ((fAreaGrid * iMaxGrids) < fArea) - fAreaGrid = fArea / static_cast(iMaxGrids); + if ((fAreaGrid * iMaxGrids) < fArea) { + fAreaGrid = fArea / static_cast(iMaxGrids); + } - float fLengthGrid = float(sqrt(fAreaGrid)); + float fLengthGrid = float(sqrt(fAreaGrid)); - _ulCtGridsX = std::max(static_cast(fLenghtX / fLengthGrid), 1); - _ulCtGridsY = std::max(static_cast(fLenghtY / fLengthGrid), 1); - } break; - case 5: - { - _ulCtGridsX = 1; // bLenghtXisZero - _ulCtGridsZ = 1; // bLenghtZisZero - _ulCtGridsY = static_cast(iMaxGrids); // bLenghtYisZero - } break; - case 6: - { - _ulCtGridsY = 1; // bLenghtYisZero - _ulCtGridsZ = 1; // bLenghtZisZero - _ulCtGridsX = static_cast(iMaxGrids); // bLenghtYisZero - } break; - case 7: - { - _ulCtGridsX = static_cast(iMaxGrids); // bLenghtXisZero - _ulCtGridsY = static_cast(iMaxGrids); // bLenghtYisZero - _ulCtGridsZ = static_cast(iMaxGrids); // bLenghtZisZero - } break; - } + _ulCtGridsX = + std::max(static_cast(fLenghtX / fLengthGrid), 1); + _ulCtGridsY = + std::max(static_cast(fLenghtY / fLengthGrid), 1); + } break; + case 5: { + _ulCtGridsX = 1; // bLenghtXisZero + _ulCtGridsZ = 1; // bLenghtZisZero + _ulCtGridsY = static_cast(iMaxGrids); // bLenghtYisZero + } break; + case 6: { + _ulCtGridsY = 1; // bLenghtYisZero + _ulCtGridsZ = 1; // bLenghtZisZero + _ulCtGridsX = static_cast(iMaxGrids); // bLenghtYisZero + } break; + case 7: { + _ulCtGridsX = static_cast(iMaxGrids); // bLenghtXisZero + _ulCtGridsY = static_cast(iMaxGrids); // bLenghtYisZero + _ulCtGridsZ = static_cast(iMaxGrids); // bLenghtZisZero + } break; + } } -void MeshGrid::SearchNearestFromPoint (const Base::Vector3f &rclPt, std::set &raclInd) const +void MeshGrid::SearchNearestFromPoint(const Base::Vector3f& rclPt, + std::set& raclInd) const { - raclInd.clear(); - Base::BoundBox3f clBB = GetBoundBox(); + raclInd.clear(); + Base::BoundBox3f clBB = GetBoundBox(); - if (clBB.IsInBox(rclPt)) - { // Point lies within - unsigned long ulX, ulY, ulZ; - Position(rclPt, ulX, ulY, ulZ); - //int nX = ulX, nY = ulY, nZ = ulZ; - unsigned long ulMaxLevel = std::max(_ulCtGridsX, std::max(_ulCtGridsY, _ulCtGridsZ)); - unsigned long ulLevel = 0; - while (raclInd.empty() && ulLevel <= ulMaxLevel) - GetHull(ulX, ulY, ulZ, ulLevel++, raclInd); - GetHull(ulX, ulY, ulZ, ulLevel, raclInd); - } - else - { // Point outside - Base::BoundBox3f::SIDE tSide = clBB.GetSideFromRay(rclPt, clBB.GetCenter() - rclPt); - switch (tSide) - { - case Base::BoundBox3f::RIGHT: - { - unsigned long nX = 0; - while (raclInd.empty() && nX < _ulCtGridsX) - { - for (unsigned long i = 0; i < _ulCtGridsY; i++) - { - for (unsigned long j = 0; j < _ulCtGridsZ; j++) - raclInd.insert(_aulGrid[nX][i][j].begin(), _aulGrid[nX][i][j].end()); - } - nX++; + if (clBB.IsInBox(rclPt)) { // Point lies within + unsigned long ulX, ulY, ulZ; + Position(rclPt, ulX, ulY, ulZ); + // int nX = ulX, nY = ulY, nZ = ulZ; + unsigned long ulMaxLevel = + std::max(_ulCtGridsX, std::max(_ulCtGridsY, _ulCtGridsZ)); + unsigned long ulLevel = 0; + while (raclInd.empty() && ulLevel <= ulMaxLevel) { + GetHull(ulX, ulY, ulZ, ulLevel++, raclInd); + } + GetHull(ulX, ulY, ulZ, ulLevel, raclInd); + } + else { // Point outside + Base::BoundBox3f::SIDE tSide = clBB.GetSideFromRay(rclPt, clBB.GetCenter() - rclPt); + switch (tSide) { + case Base::BoundBox3f::RIGHT: { + unsigned long nX = 0; + while (raclInd.empty() && nX < _ulCtGridsX) { + for (unsigned long i = 0; i < _ulCtGridsY; i++) { + for (unsigned long j = 0; j < _ulCtGridsZ; j++) { + raclInd.insert(_aulGrid[nX][i][j].begin(), _aulGrid[nX][i][j].end()); + } + } + nX++; + } + break; + } + case Base::BoundBox3f::LEFT: { + unsigned long nX = _ulCtGridsX - 1; + while (raclInd.empty() && nX < _ulCtGridsX) { + for (unsigned long i = 0; i < _ulCtGridsY; i++) { + for (unsigned long j = 0; j < _ulCtGridsZ; j++) { + raclInd.insert(_aulGrid[nX][i][j].begin(), _aulGrid[nX][i][j].end()); + } + } + nX++; + } + break; + } + case Base::BoundBox3f::TOP: { + unsigned long nY = 0; + while (raclInd.empty() && nY < _ulCtGridsY) { + for (unsigned long i = 0; i < _ulCtGridsX; i++) { + for (unsigned long j = 0; j < _ulCtGridsZ; j++) { + raclInd.insert(_aulGrid[i][nY][j].begin(), _aulGrid[i][nY][j].end()); + } + } + nY++; + } + break; + } + case Base::BoundBox3f::BOTTOM: { + unsigned long nY = _ulCtGridsY - 1; + while (raclInd.empty() && nY < _ulCtGridsY) { + for (unsigned long i = 0; i < _ulCtGridsX; i++) { + for (unsigned long j = 0; j < _ulCtGridsZ; j++) { + raclInd.insert(_aulGrid[i][nY][j].begin(), _aulGrid[i][nY][j].end()); + } + } + nY--; + } + break; + } + case Base::BoundBox3f::BACK: { + unsigned long nZ = 0; + while (raclInd.empty() && nZ < _ulCtGridsZ) { + for (unsigned long i = 0; i < _ulCtGridsX; i++) { + for (unsigned long j = 0; j < _ulCtGridsY; j++) { + raclInd.insert(_aulGrid[i][j][nZ].begin(), _aulGrid[i][j][nZ].end()); + } + } + nZ++; + } + break; + } + case Base::BoundBox3f::FRONT: { + unsigned long nZ = _ulCtGridsZ - 1; + while (raclInd.empty() && nZ < _ulCtGridsZ) { + for (unsigned long i = 0; i < _ulCtGridsX; i++) { + for (unsigned long j = 0; j < _ulCtGridsY; j++) { + raclInd.insert(_aulGrid[i][j][nZ].begin(), _aulGrid[i][j][nZ].end()); + } + } + nZ--; + } + break; + } + + default: + break; } - break; - } - case Base::BoundBox3f::LEFT: - { - unsigned long nX = _ulCtGridsX - 1; - while (raclInd.empty() && nX < _ulCtGridsX) - { - for (unsigned long i = 0; i < _ulCtGridsY; i++) - { - for (unsigned long j = 0; j < _ulCtGridsZ; j++) - raclInd.insert(_aulGrid[nX][i][j].begin(), _aulGrid[nX][i][j].end()); - } - nX++; - } - break; - } - case Base::BoundBox3f::TOP: - { - unsigned long nY = 0; - while (raclInd.empty() && nY < _ulCtGridsY) - { - for (unsigned long i = 0; i < _ulCtGridsX; i++) - { - for (unsigned long j = 0; j < _ulCtGridsZ; j++) - raclInd.insert(_aulGrid[i][nY][j].begin(), _aulGrid[i][nY][j].end()); - } - nY++; - } - break; - } - case Base::BoundBox3f::BOTTOM: - { - unsigned long nY = _ulCtGridsY - 1; - while (raclInd.empty() && nY < _ulCtGridsY) - { - for (unsigned long i = 0; i < _ulCtGridsX; i++) - { - for (unsigned long j = 0; j < _ulCtGridsZ; j++) - raclInd.insert(_aulGrid[i][nY][j].begin(), _aulGrid[i][nY][j].end()); - } - nY--; - } - break; - } - case Base::BoundBox3f::BACK: - { - unsigned long nZ = 0; - while (raclInd.empty() && nZ < _ulCtGridsZ) - { - for (unsigned long i = 0; i < _ulCtGridsX; i++) - { - for (unsigned long j = 0; j < _ulCtGridsY; j++) - raclInd.insert(_aulGrid[i][j][nZ].begin(), _aulGrid[i][j][nZ].end()); - } - nZ++; - } - break; - } - case Base::BoundBox3f::FRONT: - { - unsigned long nZ = _ulCtGridsZ - 1; - while (raclInd.empty() && nZ < _ulCtGridsZ) - { - for (unsigned long i = 0; i < _ulCtGridsX; i++) - { - for (unsigned long j = 0; j < _ulCtGridsY; j++) - raclInd.insert(_aulGrid[i][j][nZ].begin(), _aulGrid[i][j][nZ].end()); - } - nZ--; - } - break; - } - - default: - break; } - } } -void MeshGrid::GetHull (unsigned long ulX, unsigned long ulY, unsigned long ulZ, - unsigned long ulDistance, std::set &raclInd) const +void MeshGrid::GetHull(unsigned long ulX, + unsigned long ulY, + unsigned long ulZ, + unsigned long ulDistance, + std::set& raclInd) const { - int nX1 = std::max(0, int(ulX) - int(ulDistance)); - int nY1 = std::max(0, int(ulY) - int(ulDistance)); - int nZ1 = std::max(0, int(ulZ) - int(ulDistance)); - int nX2 = std::min(int(_ulCtGridsX) - 1, int(ulX) + int(ulDistance)); - int nY2 = std::min(int(_ulCtGridsY) - 1, int(ulY) + int(ulDistance)); - int nZ2 = std::min(int(_ulCtGridsZ) - 1, int(ulZ) + int(ulDistance)); + int nX1 = std::max(0, int(ulX) - int(ulDistance)); + int nY1 = std::max(0, int(ulY) - int(ulDistance)); + int nZ1 = std::max(0, int(ulZ) - int(ulDistance)); + int nX2 = std::min(int(_ulCtGridsX) - 1, int(ulX) + int(ulDistance)); + int nY2 = std::min(int(_ulCtGridsY) - 1, int(ulY) + int(ulDistance)); + int nZ2 = std::min(int(_ulCtGridsZ) - 1, int(ulZ) + int(ulDistance)); - int i, j; + int i, j; - // top plane - for (i = nX1; i <= nX2; i++) - { - for (j = nY1; j <= nY2; j++) - { - GetElements(static_cast(i), - static_cast(j), - static_cast(nZ1), - raclInd); + // top plane + for (i = nX1; i <= nX2; i++) { + for (j = nY1; j <= nY2; j++) { + GetElements(static_cast(i), + static_cast(j), + static_cast(nZ1), + raclInd); + } } - } - // bottom plane - for (i = nX1; i <= nX2; i++) - { - for (j = nY1; j <= nY2; j++) - { - GetElements(static_cast(i), - static_cast(j), - static_cast(nZ2), - raclInd); + // bottom plane + for (i = nX1; i <= nX2; i++) { + for (j = nY1; j <= nY2; j++) { + GetElements(static_cast(i), + static_cast(j), + static_cast(nZ2), + raclInd); + } } - } - // left plane - for (i = nY1; i <= nY2; i++) - { - for (j = (nZ1+1); j <= (nZ2-1); j++) - { - GetElements(static_cast(nX1), - static_cast(i), - static_cast(j), - raclInd); + // left plane + for (i = nY1; i <= nY2; i++) { + for (j = (nZ1 + 1); j <= (nZ2 - 1); j++) { + GetElements(static_cast(nX1), + static_cast(i), + static_cast(j), + raclInd); + } } - } - // right plane - for (i = nY1; i <= nY2; i++) - { - for (j = (nZ1+1); j <= (nZ2-1); j++) - { - GetElements(static_cast(nX2), - static_cast(i), - static_cast(j), - raclInd); + // right plane + for (i = nY1; i <= nY2; i++) { + for (j = (nZ1 + 1); j <= (nZ2 - 1); j++) { + GetElements(static_cast(nX2), + static_cast(i), + static_cast(j), + raclInd); + } } - } - // front plane - for (i = (nX1+1); i <= (nX2-1); i++) - { - for (j = (nZ1+1); j <= (nZ2-1); j++) - { - GetElements(static_cast(i), - static_cast(nY1), - static_cast(j), - raclInd); + // front plane + for (i = (nX1 + 1); i <= (nX2 - 1); i++) { + for (j = (nZ1 + 1); j <= (nZ2 - 1); j++) { + GetElements(static_cast(i), + static_cast(nY1), + static_cast(j), + raclInd); + } } - } - // back plane - for (i = (nX1+1); i <= (nX2-1); i++) - { - for (j = (nZ1+1); j <= (nZ2-1); j++) - { - GetElements(static_cast(i), - static_cast(nY2), - static_cast(j), - raclInd); + // back plane + for (i = (nX1 + 1); i <= (nX2 - 1); i++) { + for (j = (nZ1 + 1); j <= (nZ2 - 1); j++) { + GetElements(static_cast(i), + static_cast(nY2), + static_cast(j), + raclInd); + } } - } } -unsigned long MeshGrid::GetElements (unsigned long ulX, unsigned long ulY, unsigned long ulZ, - std::set &raclInd) const +unsigned long MeshGrid::GetElements(unsigned long ulX, + unsigned long ulY, + unsigned long ulZ, + std::set& raclInd) const { - const std::set &rclSet = _aulGrid[ulX][ulY][ulZ]; - if (!rclSet.empty()) - { - raclInd.insert(rclSet.begin(), rclSet.end()); - return rclSet.size(); - } + const std::set& rclSet = _aulGrid[ulX][ulY][ulZ]; + if (!rclSet.empty()) { + raclInd.insert(rclSet.begin(), rclSet.end()); + return rclSet.size(); + } - return 0; -} - -unsigned long MeshGrid::GetElements(const Base::Vector3f &rclPoint, std::vector& aulFacets) const -{ - unsigned long ulX, ulY, ulZ; - if (!CheckPosition(rclPoint, ulX, ulY, ulZ)) return 0; - - aulFacets.resize(_aulGrid[ulX][ulY][ulZ].size()); - - std::copy(_aulGrid[ulX][ulY][ulZ].begin(), _aulGrid[ulX][ulY][ulZ].end(), aulFacets.begin()); - return aulFacets.size(); } -unsigned long MeshGrid::GetIndexToPosition(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const +unsigned long MeshGrid::GetElements(const Base::Vector3f& rclPoint, + std::vector& aulFacets) const { - if ( !CheckPos(ulX, ulY, ulZ) ) - return ULONG_MAX; - return (ulZ * _ulCtGridsY + ulY) * _ulCtGridsX + ulX; + unsigned long ulX, ulY, ulZ; + if (!CheckPosition(rclPoint, ulX, ulY, ulZ)) { + return 0; + } + + aulFacets.resize(_aulGrid[ulX][ulY][ulZ].size()); + + std::copy(_aulGrid[ulX][ulY][ulZ].begin(), _aulGrid[ulX][ulY][ulZ].end(), aulFacets.begin()); + return aulFacets.size(); } -bool MeshGrid::GetPositionToIndex(unsigned long id, unsigned long& ulX, unsigned long& ulY, unsigned long& ulZ) const +unsigned long +MeshGrid::GetIndexToPosition(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const { - ulX = id % _ulCtGridsX; - ulY = (id/_ulCtGridsX)%_ulCtGridsY; - ulZ = id/(_ulCtGridsX*_ulCtGridsY); + if (!CheckPos(ulX, ulY, ulZ)) { + return ULONG_MAX; + } + return (ulZ * _ulCtGridsY + ulY) * _ulCtGridsX + ulX; +} - if ( !CheckPos(ulX, ulY, ulZ) ) - { - ulX = ULONG_MAX; - ulY = ULONG_MAX; - ulZ = ULONG_MAX; - return false; - } +bool MeshGrid::GetPositionToIndex(unsigned long id, + unsigned long& ulX, + unsigned long& ulY, + unsigned long& ulZ) const +{ + ulX = id % _ulCtGridsX; + ulY = (id / _ulCtGridsX) % _ulCtGridsY; + ulZ = id / (_ulCtGridsX * _ulCtGridsY); - return true; + if (!CheckPos(ulX, ulY, ulZ)) { + ulX = ULONG_MAX; + ulY = ULONG_MAX; + ulZ = ULONG_MAX; + return false; + } + + return true; } // ---------------------------------------------------------------- -MeshFacetGrid::MeshFacetGrid (const MeshKernel &rclM) -: MeshGrid(rclM) +MeshFacetGrid::MeshFacetGrid(const MeshKernel& rclM) + : MeshGrid(rclM) { - RebuildGrid(); -} - -MeshFacetGrid::MeshFacetGrid (const MeshKernel &rclM, int iCtGridPerAxis) -: MeshGrid(rclM) -{ - Rebuild(iCtGridPerAxis); -} - -MeshFacetGrid::MeshFacetGrid (const MeshKernel &rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ) -: MeshGrid(rclM) -{ - Rebuild(ulX, ulY, ulZ); -} - -MeshFacetGrid::MeshFacetGrid (const MeshKernel &rclM, float fGridLen) -: MeshGrid(rclM) -{ - Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox(); - Rebuild(std::max(static_cast(clBBMesh.LengthX() / fGridLen), 1), - std::max(static_cast(clBBMesh.LengthY() / fGridLen), 1), - std::max(static_cast(clBBMesh.LengthZ() / fGridLen), 1)); -} - -void MeshFacetGrid::Validate (const MeshKernel &rclMesh) -{ - if (_pclMesh != &rclMesh) - Attach(rclMesh); - else if (rclMesh.CountFacets() != _ulCtElements) RebuildGrid(); } -void MeshFacetGrid::Validate () +MeshFacetGrid::MeshFacetGrid(const MeshKernel& rclM, int iCtGridPerAxis) + : MeshGrid(rclM) { - if (!_pclMesh) - return; + Rebuild(iCtGridPerAxis); +} - if (_pclMesh->CountFacets() != _ulCtElements) - RebuildGrid(); +MeshFacetGrid::MeshFacetGrid(const MeshKernel& rclM, + unsigned long ulX, + unsigned long ulY, + unsigned long ulZ) + : MeshGrid(rclM) +{ + Rebuild(ulX, ulY, ulZ); +} + +MeshFacetGrid::MeshFacetGrid(const MeshKernel& rclM, float fGridLen) + : MeshGrid(rclM) +{ + Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox(); + Rebuild(std::max(static_cast(clBBMesh.LengthX() / fGridLen), 1), + std::max(static_cast(clBBMesh.LengthY() / fGridLen), 1), + std::max(static_cast(clBBMesh.LengthZ() / fGridLen), 1)); +} + +void MeshFacetGrid::Validate(const MeshKernel& rclMesh) +{ + if (_pclMesh != &rclMesh) { + Attach(rclMesh); + } + else if (rclMesh.CountFacets() != _ulCtElements) { + RebuildGrid(); + } +} + +void MeshFacetGrid::Validate() +{ + if (!_pclMesh) { + return; + } + + if (_pclMesh->CountFacets() != _ulCtElements) { + RebuildGrid(); + } } bool MeshFacetGrid::Verify() const { - if ( !_pclMesh ) - return false; // no mesh attached - if (_pclMesh->CountFacets() != _ulCtElements) - return false; // not up-to-date - - MeshGridIterator it(*this); - MeshFacetIterator cF(*_pclMesh); - for ( it.Init(); it.More(); it.Next() ) - { - std::vector aulElements; - it.GetElements( aulElements ); - for (ElementIndex element : aulElements) - { - cF.Set( element ); - if (!cF->IntersectBoundingBox(it.GetBoundBox())) - return false; // no intersection between facet although the facet is in grid + if (!_pclMesh) { + return false; // no mesh attached + } + if (_pclMesh->CountFacets() != _ulCtElements) { + return false; // not up-to-date } - } - return true; + MeshGridIterator it(*this); + MeshFacetIterator cF(*_pclMesh); + for (it.Init(); it.More(); it.Next()) { + std::vector aulElements; + it.GetElements(aulElements); + for (ElementIndex element : aulElements) { + cF.Set(element); + if (!cF->IntersectBoundingBox(it.GetBoundBox())) { + return false; // no intersection between facet although the facet is in grid + } + } + } + + return true; } -void MeshFacetGrid::RebuildGrid () +void MeshFacetGrid::RebuildGrid() { - _ulCtElements = _pclMesh->CountFacets(); + _ulCtElements = _pclMesh->CountFacets(); - InitGrid(); + InitGrid(); - // Fill data structure - MeshFacetIterator clFIter(*_pclMesh); - - unsigned long i = 0; - for (clFIter.Init(); clFIter.More(); clFIter.Next()) - { -// AddFacet(*clFIter, i++, 2.0f); - AddFacet(*clFIter, i++); - } + // Fill data structure + MeshFacetIterator clFIter(*_pclMesh); + unsigned long i = 0; + for (clFIter.Init(); clFIter.More(); clFIter.Next()) { + // AddFacet(*clFIter, i++, 2.0f); + AddFacet(*clFIter, i++); + } } -unsigned long MeshFacetGrid::SearchNearestFromPoint (const Base::Vector3f &rclPt) const +unsigned long MeshFacetGrid::SearchNearestFromPoint(const Base::Vector3f& rclPt) const { - ElementIndex ulFacetInd = ELEMENT_INDEX_MAX; - float fMinDist = FLOAT_MAX; - Base::BoundBox3f clBB = GetBoundBox(); + ElementIndex ulFacetInd = ELEMENT_INDEX_MAX; + float fMinDist = FLOAT_MAX; + Base::BoundBox3f clBB = GetBoundBox(); - if (clBB.IsInBox(rclPt)) - { // Point lies within - unsigned long ulX, ulY, ulZ; - Position(rclPt, ulX, ulY, ulZ); - float fMinGridDist = std::min(std::min(_fGridLenX, _fGridLenY), _fGridLenZ); - unsigned long ulDistance = 0; - while (fMinDist > (fMinGridDist * float(ulDistance))) - { - SearchNearestFacetInHull(ulX, ulY, ulZ, ulDistance, rclPt, ulFacetInd, fMinDist); - ulDistance++; + if (clBB.IsInBox(rclPt)) { // Point lies within + unsigned long ulX, ulY, ulZ; + Position(rclPt, ulX, ulY, ulZ); + float fMinGridDist = std::min(std::min(_fGridLenX, _fGridLenY), _fGridLenZ); + unsigned long ulDistance = 0; + while (fMinDist > (fMinGridDist * float(ulDistance))) { + SearchNearestFacetInHull(ulX, ulY, ulZ, ulDistance, rclPt, ulFacetInd, fMinDist); + ulDistance++; + } + SearchNearestFacetInHull(ulX, ulY, ulZ, ulDistance, rclPt, ulFacetInd, fMinDist); } - SearchNearestFacetInHull(ulX, ulY, ulZ, ulDistance, rclPt, ulFacetInd, fMinDist); - } - else - { // Point outside - Base::BoundBox3f::SIDE tSide = clBB.GetSideFromRay(rclPt, clBB.GetCenter() - rclPt); - switch (tSide) - { - case Base::BoundBox3f::RIGHT: - { - unsigned long nX = 0; - while ((fMinDist > ((clBB.MinX - rclPt.x) + (float(nX) * _fGridLenX))) && (nX < _ulCtGridsX)) - { - for (unsigned long i = 0; i < _ulCtGridsY; i++) - { - for (unsigned long j = 0; j < _ulCtGridsZ; j++) - SearchNearestFacetInGrid(nX, i, j, rclPt, fMinDist, ulFacetInd); - } - nX++; + else { // Point outside + Base::BoundBox3f::SIDE tSide = clBB.GetSideFromRay(rclPt, clBB.GetCenter() - rclPt); + switch (tSide) { + case Base::BoundBox3f::RIGHT: { + unsigned long nX = 0; + while ((fMinDist > ((clBB.MinX - rclPt.x) + (float(nX) * _fGridLenX))) + && (nX < _ulCtGridsX)) { + for (unsigned long i = 0; i < _ulCtGridsY; i++) { + for (unsigned long j = 0; j < _ulCtGridsZ; j++) { + SearchNearestFacetInGrid(nX, i, j, rclPt, fMinDist, ulFacetInd); + } + } + nX++; + } + break; + } + case Base::BoundBox3f::LEFT: { + unsigned long nX = _ulCtGridsX - 1; + while ((fMinDist > ((rclPt.x - clBB.MinX) + (float(nX) * _fGridLenX))) + && (nX < _ulCtGridsX)) { + for (unsigned long i = 0; i < _ulCtGridsY; i++) { + for (unsigned long j = 0; j < _ulCtGridsZ; j++) { + SearchNearestFacetInGrid(nX, i, j, rclPt, fMinDist, ulFacetInd); + } + } + nX--; + } + break; + } + case Base::BoundBox3f::TOP: { + unsigned long nY = 0; + while ((fMinDist > ((clBB.MinY - rclPt.y) + (float(nY) * _fGridLenY))) + && (nY < _ulCtGridsY)) { + for (unsigned long i = 0; i < _ulCtGridsX; i++) { + for (unsigned long j = 0; j < _ulCtGridsZ; j++) { + SearchNearestFacetInGrid(i, nY, j, rclPt, fMinDist, ulFacetInd); + } + } + nY++; + } + break; + } + case Base::BoundBox3f::BOTTOM: { + unsigned long nY = _ulCtGridsY - 1; + while ((fMinDist > ((rclPt.y - clBB.MinY) + (float(nY) * _fGridLenY))) + && (nY < _ulCtGridsY)) { + for (unsigned long i = 0; i < _ulCtGridsX; i++) { + for (unsigned long j = 0; j < _ulCtGridsZ; j++) { + SearchNearestFacetInGrid(i, nY, j, rclPt, fMinDist, ulFacetInd); + } + } + nY--; + } + break; + } + case Base::BoundBox3f::BACK: { + unsigned long nZ = 0; + while ((fMinDist > ((clBB.MinZ - rclPt.z) + (float(nZ) * _fGridLenZ))) + && (nZ < _ulCtGridsZ)) { + for (unsigned long i = 0; i < _ulCtGridsX; i++) { + for (unsigned long j = 0; j < _ulCtGridsY; j++) { + SearchNearestFacetInGrid(i, j, nZ, rclPt, fMinDist, ulFacetInd); + } + } + nZ++; + } + break; + } + case Base::BoundBox3f::FRONT: { + unsigned long nZ = _ulCtGridsZ - 1; + while ((fMinDist > ((rclPt.z - clBB.MinZ) + (float(nZ) * _fGridLenZ))) + && (nZ < _ulCtGridsZ)) { + for (unsigned long i = 0; i < _ulCtGridsX; i++) { + for (unsigned long j = 0; j < _ulCtGridsY; j++) { + SearchNearestFacetInGrid(i, j, nZ, rclPt, fMinDist, ulFacetInd); + } + } + nZ--; + } + break; + } + default: + break; } - break; - } - case Base::BoundBox3f::LEFT: - { - unsigned long nX = _ulCtGridsX - 1; - while ((fMinDist > ((rclPt.x - clBB.MinX) + (float(nX) * _fGridLenX))) && (nX < _ulCtGridsX)) - { - for (unsigned long i = 0; i < _ulCtGridsY; i++) - { - for (unsigned long j = 0; j < _ulCtGridsZ; j++) - SearchNearestFacetInGrid(nX, i, j, rclPt, fMinDist, ulFacetInd); - } - nX--; - } - break; - } - case Base::BoundBox3f::TOP: - { - unsigned long nY = 0; - while ((fMinDist > ((clBB.MinY - rclPt.y) + (float(nY) * _fGridLenY))) && (nY < _ulCtGridsY)) - { - for (unsigned long i = 0; i < _ulCtGridsX; i++) - { - for (unsigned long j = 0; j < _ulCtGridsZ; j++) - SearchNearestFacetInGrid(i, nY, j, rclPt, fMinDist, ulFacetInd); - } - nY++; - } - break; - } - case Base::BoundBox3f::BOTTOM: - { - unsigned long nY = _ulCtGridsY - 1; - while ((fMinDist > ((rclPt.y - clBB.MinY) + (float(nY) * _fGridLenY))) && (nY < _ulCtGridsY)) - { - for (unsigned long i = 0; i < _ulCtGridsX; i++) - { - for (unsigned long j = 0; j < _ulCtGridsZ; j++) - SearchNearestFacetInGrid(i, nY, j, rclPt, fMinDist, ulFacetInd); - } - nY--; - } - break; - } - case Base::BoundBox3f::BACK: - { - unsigned long nZ = 0; - while ((fMinDist > ((clBB.MinZ - rclPt.z) + (float(nZ) * _fGridLenZ))) && (nZ < _ulCtGridsZ)) - { - for (unsigned long i = 0; i < _ulCtGridsX; i++) - { - for (unsigned long j = 0; j < _ulCtGridsY; j++) - SearchNearestFacetInGrid(i, j, nZ, rclPt, fMinDist, ulFacetInd); - } - nZ++; - } - break; - } - case Base::BoundBox3f::FRONT: - { - unsigned long nZ = _ulCtGridsZ - 1; - while ((fMinDist > ((rclPt.z - clBB.MinZ) + (float(nZ) * _fGridLenZ))) && (nZ < _ulCtGridsZ)) - { - for (unsigned long i = 0; i < _ulCtGridsX; i++) - { - for (unsigned long j = 0; j < _ulCtGridsY; j++) - SearchNearestFacetInGrid(i, j, nZ, rclPt, fMinDist, ulFacetInd); - } - nZ--; - } - break; - } - default: - break; } - } - return ulFacetInd; + return ulFacetInd; } -unsigned long MeshFacetGrid::SearchNearestFromPoint (const Base::Vector3f &rclPt, float fMaxSearchArea) const +unsigned long MeshFacetGrid::SearchNearestFromPoint(const Base::Vector3f& rclPt, + float fMaxSearchArea) const { - std::vector aulFacets; - ElementIndex ulFacetInd = ELEMENT_INDEX_MAX; - float fMinDist = fMaxSearchArea; + std::vector aulFacets; + ElementIndex ulFacetInd = ELEMENT_INDEX_MAX; + float fMinDist = fMaxSearchArea; - MeshAlgorithm clFTool(*_pclMesh); + MeshAlgorithm clFTool(*_pclMesh); - Base::BoundBox3f clBB(rclPt.x - fMaxSearchArea, rclPt.y - fMaxSearchArea, rclPt.z - fMaxSearchArea, - rclPt.x + fMaxSearchArea, rclPt.y + fMaxSearchArea, rclPt.z + fMaxSearchArea); + Base::BoundBox3f clBB(rclPt.x - fMaxSearchArea, + rclPt.y - fMaxSearchArea, + rclPt.z - fMaxSearchArea, + rclPt.x + fMaxSearchArea, + rclPt.y + fMaxSearchArea, + rclPt.z + fMaxSearchArea); - Inside(clBB, aulFacets, rclPt, fMaxSearchArea, true); + Inside(clBB, aulFacets, rclPt, fMaxSearchArea, true); - for (ElementIndex facet : aulFacets) - { - float fDist; + for (ElementIndex facet : aulFacets) { + float fDist; - if (clFTool.Distance(rclPt, facet, fMinDist, fDist)) - { - fMinDist = fDist; - ulFacetInd = facet; + if (clFTool.Distance(rclPt, facet, fMinDist, fDist)) { + fMinDist = fDist; + ulFacetInd = facet; + } } - } - return ulFacetInd; + return ulFacetInd; } -void MeshFacetGrid::SearchNearestFacetInHull (unsigned long ulX, unsigned long ulY, unsigned long ulZ, - unsigned long ulDistance, const Base::Vector3f &rclPt, - ElementIndex &rulFacetInd, float &rfMinDist) const +void MeshFacetGrid::SearchNearestFacetInHull(unsigned long ulX, + unsigned long ulY, + unsigned long ulZ, + unsigned long ulDistance, + const Base::Vector3f& rclPt, + ElementIndex& rulFacetInd, + float& rfMinDist) const { - int nX1 = std::max(0, int(ulX) - int(ulDistance)); - int nY1 = std::max(0, int(ulY) - int(ulDistance)); - int nZ1 = std::max(0, int(ulZ) - int(ulDistance)); - int nX2 = std::min(int(_ulCtGridsX) - 1, int(ulX) + int(ulDistance)); - int nY2 = std::min(int(_ulCtGridsY) - 1, int(ulY) + int(ulDistance)); - int nZ2 = std::min(int(_ulCtGridsZ) - 1, int(ulZ) + int(ulDistance)); + int nX1 = std::max(0, int(ulX) - int(ulDistance)); + int nY1 = std::max(0, int(ulY) - int(ulDistance)); + int nZ1 = std::max(0, int(ulZ) - int(ulDistance)); + int nX2 = std::min(int(_ulCtGridsX) - 1, int(ulX) + int(ulDistance)); + int nY2 = std::min(int(_ulCtGridsY) - 1, int(ulY) + int(ulDistance)); + int nZ2 = std::min(int(_ulCtGridsZ) - 1, int(ulZ) + int(ulDistance)); - int i, j; + int i, j; - // top plane - for (i = nX1; i <= nX2; i++) - { - for (j = nY1; j <= nY2; j++) - { - SearchNearestFacetInGrid(static_cast(i), - static_cast(j), - static_cast(nZ1), - rclPt, rfMinDist, rulFacetInd); + // top plane + for (i = nX1; i <= nX2; i++) { + for (j = nY1; j <= nY2; j++) { + SearchNearestFacetInGrid(static_cast(i), + static_cast(j), + static_cast(nZ1), + rclPt, + rfMinDist, + rulFacetInd); + } } - } - // bottom plane - for (i = nX1; i <= nX2; i++) - { - for (j = nY1; j <= nY2; j++) - { - SearchNearestFacetInGrid(static_cast(i), - static_cast(j), - static_cast(nZ2), - rclPt, rfMinDist, rulFacetInd); + // bottom plane + for (i = nX1; i <= nX2; i++) { + for (j = nY1; j <= nY2; j++) { + SearchNearestFacetInGrid(static_cast(i), + static_cast(j), + static_cast(nZ2), + rclPt, + rfMinDist, + rulFacetInd); + } } - } - // left plane - for (i = nY1; i <= nY2; i++) - { - for (j = (nZ1+1); j <= (nZ2-1); j++) - { - SearchNearestFacetInGrid(static_cast(nX1), - static_cast(i), - static_cast(j), - rclPt, rfMinDist, rulFacetInd); + // left plane + for (i = nY1; i <= nY2; i++) { + for (j = (nZ1 + 1); j <= (nZ2 - 1); j++) { + SearchNearestFacetInGrid(static_cast(nX1), + static_cast(i), + static_cast(j), + rclPt, + rfMinDist, + rulFacetInd); + } } - } - // right plane - for (i = nY1; i <= nY2; i++) - { - for (j = (nZ1+1); j <= (nZ2-1); j++) - { - SearchNearestFacetInGrid(static_cast(nX2), - static_cast(i), - static_cast(j), - rclPt, rfMinDist, rulFacetInd); + // right plane + for (i = nY1; i <= nY2; i++) { + for (j = (nZ1 + 1); j <= (nZ2 - 1); j++) { + SearchNearestFacetInGrid(static_cast(nX2), + static_cast(i), + static_cast(j), + rclPt, + rfMinDist, + rulFacetInd); + } } - } - // front plane - for (i = (nX1+1); i <= (nX2-1); i++) - { - for (j = (nZ1+1); j <= (nZ2-1); j++) - { - SearchNearestFacetInGrid(static_cast(i), - static_cast(nY1), - static_cast(j), - rclPt, rfMinDist, rulFacetInd); + // front plane + for (i = (nX1 + 1); i <= (nX2 - 1); i++) { + for (j = (nZ1 + 1); j <= (nZ2 - 1); j++) { + SearchNearestFacetInGrid(static_cast(i), + static_cast(nY1), + static_cast(j), + rclPt, + rfMinDist, + rulFacetInd); + } } - } - // back plane - for (i = (nX1+1); i <= (nX2-1); i++) - { - for (j = (nZ1+1); j <= (nZ2-1); j++) - { - SearchNearestFacetInGrid(static_cast(i), - static_cast(nY2), - static_cast(j), - rclPt, rfMinDist, rulFacetInd); + // back plane + for (i = (nX1 + 1); i <= (nX2 - 1); i++) { + for (j = (nZ1 + 1); j <= (nZ2 - 1); j++) { + SearchNearestFacetInGrid(static_cast(i), + static_cast(nY2), + static_cast(j), + rclPt, + rfMinDist, + rulFacetInd); + } } - } } -void MeshFacetGrid::SearchNearestFacetInGrid(unsigned long ulX, unsigned long ulY, unsigned long ulZ, - const Base::Vector3f &rclPt, float &rfMinDist, - ElementIndex &rulFacetInd) const +void MeshFacetGrid::SearchNearestFacetInGrid(unsigned long ulX, + unsigned long ulY, + unsigned long ulZ, + const Base::Vector3f& rclPt, + float& rfMinDist, + ElementIndex& rulFacetInd) const { - const std::set &rclSet = _aulGrid[ulX][ulY][ulZ]; - for (ElementIndex pI : rclSet) - { - float fDist = _pclMesh->GetFacet(pI).DistanceToPoint(rclPt); - if (fDist < rfMinDist) - { - rfMinDist = fDist; - rulFacetInd = pI; + const std::set& rclSet = _aulGrid[ulX][ulY][ulZ]; + for (ElementIndex pI : rclSet) { + float fDist = _pclMesh->GetFacet(pI).DistanceToPoint(rclPt); + if (fDist < rfMinDist) { + rfMinDist = fDist; + rulFacetInd = pI; + } } - } } //---------------------------------------------------------------------------- -MeshPointGrid::MeshPointGrid (const MeshKernel &rclM) - : MeshGrid(rclM) +MeshPointGrid::MeshPointGrid(const MeshKernel& rclM) + : MeshGrid(rclM) { - RebuildGrid(); -} - -MeshPointGrid::MeshPointGrid () - : MeshGrid() -{ -} - -MeshPointGrid::MeshPointGrid (const MeshKernel &rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ) - : MeshGrid(rclM) -{ - Rebuild(ulX, ulY, ulZ); -} - -MeshPointGrid::MeshPointGrid (const MeshKernel &rclM, int iCtGridPerAxis) - : MeshGrid(rclM) -{ - Rebuild(iCtGridPerAxis); -} - -MeshPointGrid::MeshPointGrid (const MeshKernel &rclM, float fGridLen) - : MeshGrid(rclM) -{ - Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox(); - Rebuild(std::max(static_cast(clBBMesh.LengthX() / fGridLen), 1), - std::max(static_cast(clBBMesh.LengthY() / fGridLen), 1), - std::max(static_cast(clBBMesh.LengthZ() / fGridLen), 1)); -} - -void MeshPointGrid::AddPoint (const MeshPoint &rclPt, ElementIndex ulPtIndex, float fEpsilon) -{ - (void)fEpsilon; - unsigned long ulX, ulY, ulZ; - Pos(Base::Vector3f(rclPt.x, rclPt.y, rclPt.z), ulX, ulY, ulZ); - if ( (ulX < _ulCtGridsX) && (ulY < _ulCtGridsY) && (ulZ < _ulCtGridsZ) ) - _aulGrid[ulX][ulY][ulZ].insert(ulPtIndex); -} - -void MeshPointGrid::Validate (const MeshKernel &rclMesh) -{ - if (_pclMesh != &rclMesh) - Attach(rclMesh); - else if (rclMesh.CountPoints() != _ulCtElements) RebuildGrid(); } -void MeshPointGrid::Validate () -{ - if (!_pclMesh) - return; +MeshPointGrid::MeshPointGrid() + : MeshGrid() +{} - if (_pclMesh->CountPoints() != _ulCtElements) - RebuildGrid(); +MeshPointGrid::MeshPointGrid(const MeshKernel& rclM, + unsigned long ulX, + unsigned long ulY, + unsigned long ulZ) + : MeshGrid(rclM) +{ + Rebuild(ulX, ulY, ulZ); +} + +MeshPointGrid::MeshPointGrid(const MeshKernel& rclM, int iCtGridPerAxis) + : MeshGrid(rclM) +{ + Rebuild(iCtGridPerAxis); +} + +MeshPointGrid::MeshPointGrid(const MeshKernel& rclM, float fGridLen) + : MeshGrid(rclM) +{ + Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox(); + Rebuild(std::max(static_cast(clBBMesh.LengthX() / fGridLen), 1), + std::max(static_cast(clBBMesh.LengthY() / fGridLen), 1), + std::max(static_cast(clBBMesh.LengthZ() / fGridLen), 1)); +} + +void MeshPointGrid::AddPoint(const MeshPoint& rclPt, ElementIndex ulPtIndex, float fEpsilon) +{ + (void)fEpsilon; + unsigned long ulX, ulY, ulZ; + Pos(Base::Vector3f(rclPt.x, rclPt.y, rclPt.z), ulX, ulY, ulZ); + if ((ulX < _ulCtGridsX) && (ulY < _ulCtGridsY) && (ulZ < _ulCtGridsZ)) { + _aulGrid[ulX][ulY][ulZ].insert(ulPtIndex); + } +} + +void MeshPointGrid::Validate(const MeshKernel& rclMesh) +{ + if (_pclMesh != &rclMesh) { + Attach(rclMesh); + } + else if (rclMesh.CountPoints() != _ulCtElements) { + RebuildGrid(); + } +} + +void MeshPointGrid::Validate() +{ + if (!_pclMesh) { + return; + } + + if (_pclMesh->CountPoints() != _ulCtElements) { + RebuildGrid(); + } } bool MeshPointGrid::Verify() const { - if ( !_pclMesh ) - return false; // no mesh attached - if (_pclMesh->CountFacets() != _ulCtElements) - return false; // not up-to-date - - MeshGridIterator it(*this); - MeshPointIterator cP(*_pclMesh); - for ( it.Init(); it.More(); it.Next() ) - { - std::vector aulElements; - it.GetElements( aulElements ); - for (ElementIndex element : aulElements) - { - cP.Set( element ); - if (!it.GetBoundBox().IsInBox(*cP)) - return false; // point doesn't lie inside the grid element + if (!_pclMesh) { + return false; // no mesh attached + } + if (_pclMesh->CountFacets() != _ulCtElements) { + return false; // not up-to-date } - } - return true; + MeshGridIterator it(*this); + MeshPointIterator cP(*_pclMesh); + for (it.Init(); it.More(); it.Next()) { + std::vector aulElements; + it.GetElements(aulElements); + for (ElementIndex element : aulElements) { + cP.Set(element); + if (!it.GetBoundBox().IsInBox(*cP)) { + return false; // point doesn't lie inside the grid element + } + } + } + + return true; } -void MeshPointGrid::RebuildGrid () +void MeshPointGrid::RebuildGrid() { - _ulCtElements = _pclMesh->CountPoints(); + _ulCtElements = _pclMesh->CountPoints(); - InitGrid(); + InitGrid(); - // Fill data structure + // Fill data structure - MeshPointIterator cPIter(*_pclMesh); + MeshPointIterator cPIter(*_pclMesh); - unsigned long i = 0; - for (cPIter.Init(); cPIter.More(); cPIter.Next()) - { - AddPoint(*cPIter, i++); - } + unsigned long i = 0; + for (cPIter.Init(); cPIter.More(); cPIter.Next()) { + AddPoint(*cPIter, i++); + } } -void MeshPointGrid::Pos (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const +void MeshPointGrid::Pos(const Base::Vector3f& rclPoint, + unsigned long& rulX, + unsigned long& rulY, + unsigned long& rulZ) const { - rulX = static_cast((rclPoint.x - _fMinX) / _fGridLenX); - rulY = static_cast((rclPoint.y - _fMinY) / _fGridLenY); - rulZ = static_cast((rclPoint.z - _fMinZ) / _fGridLenZ); + rulX = static_cast((rclPoint.x - _fMinX) / _fGridLenX); + rulY = static_cast((rclPoint.y - _fMinY) / _fGridLenY); + rulZ = static_cast((rclPoint.z - _fMinZ) / _fGridLenZ); } -unsigned long MeshPointGrid::FindElements (const Base::Vector3f &rclPoint, std::set& aulElements) const +unsigned long MeshPointGrid::FindElements(const Base::Vector3f& rclPoint, + std::set& aulElements) const { - unsigned long ulX, ulY, ulZ; - Pos(rclPoint, ulX, ulY, ulZ); + unsigned long ulX, ulY, ulZ; + Pos(rclPoint, ulX, ulY, ulZ); - // check if the given point is inside the grid structure - if ( (ulX < _ulCtGridsX) && (ulY < _ulCtGridsY) && (ulZ < _ulCtGridsZ) ) - { - return GetElements(ulX, ulY, ulZ, aulElements); - } + // check if the given point is inside the grid structure + if ((ulX < _ulCtGridsX) && (ulY < _ulCtGridsY) && (ulZ < _ulCtGridsZ)) { + return GetElements(ulX, ulY, ulZ, aulElements); + } - return 0; + return 0; } // ---------------------------------------------------------------- -MeshGridIterator::MeshGridIterator (const MeshGrid &rclG) - : _rclGrid(rclG) - , _clPt(0.0f, 0.0f, 0.0f) - , _clDir(0.0f, 0.0f, 0.0f) +MeshGridIterator::MeshGridIterator(const MeshGrid& rclG) + : _rclGrid(rclG) + , _clPt(0.0f, 0.0f, 0.0f) + , _clDir(0.0f, 0.0f, 0.0f) +{} + +bool MeshGridIterator::InitOnRay(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + float fMaxSearchArea, + std::vector& raulElements) { + bool ret = InitOnRay(rclPt, rclDir, raulElements); + _fMaxSearchArea = fMaxSearchArea; + return ret; } -bool MeshGridIterator::InitOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, float fMaxSearchArea, - std::vector &raulElements) +bool MeshGridIterator::InitOnRay(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + std::vector& raulElements) { - bool ret = InitOnRay (rclPt, rclDir, raulElements); - _fMaxSearchArea = fMaxSearchArea; - return ret; -} + // needed in NextOnRay() to avoid an infinite loop + _cSearchPositions.clear(); -bool MeshGridIterator::InitOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, - std::vector &raulElements) -{ - // needed in NextOnRay() to avoid an infinite loop - _cSearchPositions.clear(); + _fMaxSearchArea = FLOAT_MAX; - _fMaxSearchArea = FLOAT_MAX; + raulElements.clear(); - raulElements.clear(); + _clPt = rclPt; + _clDir = rclDir; + _bValidRay = false; - _clPt = rclPt; - _clDir = rclDir; - _bValidRay = false; - - // point lies within global BB - if (_rclGrid.GetBoundBox().IsInBox(rclPt)) - { // Determine the voxel by the starting point - _rclGrid.Position(rclPt, _ulX, _ulY, _ulZ); - raulElements.insert(raulElements.end(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end()); - _bValidRay = true; - } - else - { // Start point outside - Base::Vector3f cP0, cP1; - if (_rclGrid.GetBoundBox().IntersectWithLine(rclPt, rclDir, cP0, cP1)) - { // determine the next point - if ((cP0 - rclPt).Length() < (cP1 - rclPt).Length()) - _rclGrid.Position(cP0, _ulX, _ulY, _ulZ); - else - _rclGrid.Position(cP1, _ulX, _ulY, _ulZ); - - raulElements.insert(raulElements.end(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end()); - _bValidRay = true; + // point lies within global BB + if (_rclGrid.GetBoundBox().IsInBox(rclPt)) { // Determine the voxel by the starting point + _rclGrid.Position(rclPt, _ulX, _ulY, _ulZ); + raulElements.insert(raulElements.end(), + _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), + _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end()); + _bValidRay = true; } - } + else { // Start point outside + Base::Vector3f cP0, cP1; + if (_rclGrid.GetBoundBox().IntersectWithLine(rclPt, + rclDir, + cP0, + cP1)) { // determine the next point + if ((cP0 - rclPt).Length() < (cP1 - rclPt).Length()) { + _rclGrid.Position(cP0, _ulX, _ulY, _ulZ); + } + else { + _rclGrid.Position(cP1, _ulX, _ulY, _ulZ); + } - return _bValidRay; -} - -bool MeshGridIterator::NextOnRay (std::vector &raulElements) -{ - if (!_bValidRay) - return false; // not initialized or beam exited - - raulElements.clear(); - - Base::Vector3f clIntersectPoint; - - // Look for the next adjacent BB on the search beam - Base::BoundBox3f::SIDE tSide = _rclGrid.GetBoundBox(_ulX, _ulY, _ulZ).GetSideFromRay(_clPt, _clDir, clIntersectPoint); - - // Search area - // - if ((_clPt-clIntersectPoint).Length() > _fMaxSearchArea) - { - _bValidRay = false; - } - else - { - switch (tSide) - { - case Base::BoundBox3f::LEFT: _ulX--; break; - case Base::BoundBox3f::RIGHT: _ulX++; break; - case Base::BoundBox3f::BOTTOM: _ulY--; break; - case Base::BoundBox3f::TOP: _ulY++; break; - case Base::BoundBox3f::FRONT: _ulZ--; break; - case Base::BoundBox3f::BACK: _ulZ++; break; - - default: - case Base::BoundBox3f::INVALID: - _bValidRay = false; - break; + raulElements.insert(raulElements.end(), + _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), + _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end()); + _bValidRay = true; + } } - GridElement pos(_ulX, _ulY, _ulZ); - if ( _cSearchPositions.find( pos ) != _cSearchPositions.end() ) - _bValidRay = false; // grid element already visited => result from GetSideFromRay invalid - } - - if (_bValidRay && _rclGrid.CheckPos(_ulX, _ulY, _ulZ)) - { - GridElement pos(_ulX, _ulY, _ulZ); _cSearchPositions.insert(pos); - raulElements.insert(raulElements.end(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end()); - } - else - _bValidRay = false; // Beam leaked - - return _bValidRay; + return _bValidRay; +} + +bool MeshGridIterator::NextOnRay(std::vector& raulElements) +{ + if (!_bValidRay) { + return false; // not initialized or beam exited + } + + raulElements.clear(); + + Base::Vector3f clIntersectPoint; + + // Look for the next adjacent BB on the search beam + Base::BoundBox3f::SIDE tSide = + _rclGrid.GetBoundBox(_ulX, _ulY, _ulZ).GetSideFromRay(_clPt, _clDir, clIntersectPoint); + + // Search area + // + if ((_clPt - clIntersectPoint).Length() > _fMaxSearchArea) { + _bValidRay = false; + } + else { + switch (tSide) { + case Base::BoundBox3f::LEFT: + _ulX--; + break; + case Base::BoundBox3f::RIGHT: + _ulX++; + break; + case Base::BoundBox3f::BOTTOM: + _ulY--; + break; + case Base::BoundBox3f::TOP: + _ulY++; + break; + case Base::BoundBox3f::FRONT: + _ulZ--; + break; + case Base::BoundBox3f::BACK: + _ulZ++; + break; + + default: + case Base::BoundBox3f::INVALID: + _bValidRay = false; + break; + } + + GridElement pos(_ulX, _ulY, _ulZ); + if (_cSearchPositions.find(pos) != _cSearchPositions.end()) { + _bValidRay = + false; // grid element already visited => result from GetSideFromRay invalid + } + } + + if (_bValidRay && _rclGrid.CheckPos(_ulX, _ulY, _ulZ)) { + GridElement pos(_ulX, _ulY, _ulZ); + _cSearchPositions.insert(pos); + raulElements.insert(raulElements.end(), + _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), + _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end()); + } + else { + _bValidRay = false; // Beam leaked + } + + return _bValidRay; } diff --git a/src/Mod/Mesh/App/Core/Grid.h b/src/Mod/Mesh/App/Core/Grid.h index 3873ec3177..ab9ebd5be9 100644 --- a/src/Mod/Mesh/App/Core/Grid.h +++ b/src/Mod/Mesh/App/Core/Grid.h @@ -30,12 +30,13 @@ #include "MeshKernel.h" -#define MESH_CT_GRID 256 // Default value for number of elements per grid -#define MESH_MAX_GRIDS 100000 // Default value for maximum number of grids -#define MESH_CT_GRID_PER_AXIS 20 +#define MESH_CT_GRID 256 // Default value for number of elements per grid +#define MESH_MAX_GRIDS 100000 // Default value for maximum number of grids +#define MESH_CT_GRID_PER_AXIS 20 -namespace MeshCore { +namespace MeshCore +{ class MeshKernel; class MeshGeomFacet; @@ -54,123 +55,162 @@ class MeshGrid; class MeshExport MeshGrid { protected: - /** @name Construction */ - //@{ - /// Construction - explicit MeshGrid (const MeshKernel &rclM); - /// Construction - MeshGrid (); - //@} + /** @name Construction */ + //@{ + /// Construction + explicit MeshGrid(const MeshKernel& rclM); + /// Construction + MeshGrid(); + //@} public: - /// Destruction - virtual ~MeshGrid () = default; + /// Destruction + virtual ~MeshGrid() = default; public: - /** Attaches the mesh kernel to this grid, an already attached mesh gets detached. The grid gets rebuilt - * automatically. */ - virtual void Attach (const MeshKernel &rclM); - /** Rebuilds the grid structure. */ - virtual void Rebuild (unsigned long ulPerGrid = MESH_CT_GRID, unsigned long ulMaxGrid = MESH_MAX_GRIDS); - /** Rebuilds the grid structure. */ - virtual void Rebuild (int iCtGridPerAxis = MESH_CT_GRID_PER_AXIS); - /** Rebuilds the grid structure. */ - virtual void Rebuild (unsigned long ulX, unsigned long ulY, unsigned long ulZ); + /** Attaches the mesh kernel to this grid, an already attached mesh gets detached. The grid gets + * rebuilt automatically. */ + virtual void Attach(const MeshKernel& rclM); + /** Rebuilds the grid structure. */ + virtual void Rebuild(unsigned long ulPerGrid = MESH_CT_GRID, + unsigned long ulMaxGrid = MESH_MAX_GRIDS); + /** Rebuilds the grid structure. */ + virtual void Rebuild(int iCtGridPerAxis = MESH_CT_GRID_PER_AXIS); + /** Rebuilds the grid structure. */ + virtual void Rebuild(unsigned long ulX, unsigned long ulY, unsigned long ulZ); - /** @name Search */ - //@{ - /** Searches for elements lying in the intersection area of the grid and the bounding box. */ - virtual unsigned long Inside (const Base::BoundBox3f &rclBB, std::vector &raulElements, bool bDelDoubles = true) const; - /** Searches for elements lying in the intersection area of the grid and the bounding box. */ - virtual unsigned long Inside (const Base::BoundBox3f &rclBB, std::set &raulElementss) const; - /** Searches for elements lying in the intersection area of the grid and the bounding box. */ - virtual unsigned long Inside (const Base::BoundBox3f &rclBB, std::vector &raulElements, - const Base::Vector3f &rclOrg, float fMaxDist, bool bDelDoubles = true) const; - /** Searches for the nearest grids that contain elements from a point, the result are grid indices. */ - void SearchNearestFromPoint (const Base::Vector3f &rclPt, std::set &rclInd) const; - //@} + /** @name Search */ + //@{ + /** Searches for elements lying in the intersection area of the grid and the bounding box. */ + virtual unsigned long Inside(const Base::BoundBox3f& rclBB, + std::vector& raulElements, + bool bDelDoubles = true) const; + /** Searches for elements lying in the intersection area of the grid and the bounding box. */ + virtual unsigned long Inside(const Base::BoundBox3f& rclBB, + std::set& raulElementss) const; + /** Searches for elements lying in the intersection area of the grid and the bounding box. */ + virtual unsigned long Inside(const Base::BoundBox3f& rclBB, + std::vector& raulElements, + const Base::Vector3f& rclOrg, + float fMaxDist, + bool bDelDoubles = true) const; + /** Searches for the nearest grids that contain elements from a point, the result are grid + * indices. */ + void SearchNearestFromPoint(const Base::Vector3f& rclPt, std::set& rclInd) const; + //@} - /** @name Getters */ - //@{ - /** Returns the indices of the elements in the given grid. */ - unsigned long GetElements (unsigned long ulX, unsigned long ulY, unsigned long ulZ, std::set &raclInd) const; - unsigned long GetElements (const Base::Vector3f &rclPoint, std::vector& aulFacets) const; - //@} + /** @name Getters */ + //@{ + /** Returns the indices of the elements in the given grid. */ + unsigned long GetElements(unsigned long ulX, + unsigned long ulY, + unsigned long ulZ, + std::set& raclInd) const; + unsigned long GetElements(const Base::Vector3f& rclPoint, + std::vector& aulFacets) const; + //@} - /** Returns the lengths of the grid elements in x,y and z direction. */ - virtual void GetGridLengths (float &rfLenX, float &rfLenY, float &rfLenZ) const - { rfLenX = _fGridLenX; rfLenY = _fGridLenY; rfLenZ = _fGridLenZ; } - /** Returns the number of grid elements in x,y and z direction. */ - virtual void GetCtGrids (unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const - { rulX = _ulCtGridsX; rulY = _ulCtGridsY; rulZ = _ulCtGridsZ; } + /** Returns the lengths of the grid elements in x,y and z direction. */ + virtual void GetGridLengths(float& rfLenX, float& rfLenY, float& rfLenZ) const + { + rfLenX = _fGridLenX; + rfLenY = _fGridLenY; + rfLenZ = _fGridLenZ; + } + /** Returns the number of grid elements in x,y and z direction. */ + virtual void GetCtGrids(unsigned long& rulX, unsigned long& rulY, unsigned long& rulZ) const + { + rulX = _ulCtGridsX; + rulY = _ulCtGridsY; + rulZ = _ulCtGridsZ; + } - /** @name Boundings */ - //@{ - /** Returns the bounding box of a given grid element. */ - inline Base::BoundBox3f GetBoundBox (unsigned long ulX, unsigned long ulY, unsigned long ulZ) const; - /** Returns the bounding box of the whole. */ - inline Base::BoundBox3f GetBoundBox () const; - /** Returns an extended bounding box of the mesh object. */ - inline Base::BoundBox3f GetMeshBoundBox () const; - //@} - /** Returns an index for the given grid position. If the specified triple is not a valid grid position ULONG_MAX is returned. - * If the index is valid than its value is between zero and the number of grid elements. For each different grid position - * a different index is returned. - */ - unsigned long GetIndexToPosition(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const; - /** Returns the grid position to the given index. If the index is equal to or higher than the number of grid elements false is returned - * and the triple is set to ULONG_MAX. - */ - bool GetPositionToIndex(unsigned long id, unsigned long& ulX, unsigned long& ulY, unsigned long& ulZ) const; - /** Returns the number of elements in a given grid. */ - unsigned long GetCtElements(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const - { return static_cast(_aulGrid[ulX][ulY][ulZ].size()); } - /** Validates the grid structure and rebuilds it if needed. Must be implemented in sub-classes. */ - virtual void Validate (const MeshKernel &rclM) = 0; - /** Verifies the grid structure and returns false if inconsistencies are found. */ - virtual bool Verify() const = 0; - /** Checks whether the point is inside the grid. In case it is inside true is returned with the grid position, - * otherwise false is returned and the grid position is undefined. - */ - bool CheckPosition (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const; - /** Returns the indices of the grid this point lies in. If the point is outside the grid the indices of - * the nearest grid element are taken.*/ - virtual void Position (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const; - /** Checks if this is a valid grid position. */ - inline bool CheckPos (unsigned long ulX, unsigned long ulY, unsigned long ulZ) const; - /** Get the indices of all elements lying in the grids around a given grid with distance \a ulDistance. */ - void GetHull (unsigned long ulX, unsigned long ulY, unsigned long ulZ, unsigned long ulDistance, std::set &raclInd) const; + /** @name Boundings */ + //@{ + /** Returns the bounding box of a given grid element. */ + inline Base::BoundBox3f + GetBoundBox(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const; + /** Returns the bounding box of the whole. */ + inline Base::BoundBox3f GetBoundBox() const; + /** Returns an extended bounding box of the mesh object. */ + inline Base::BoundBox3f GetMeshBoundBox() const; + //@} + /** Returns an index for the given grid position. If the specified triple is not a valid grid + * position ULONG_MAX is returned. If the index is valid than its value is between zero and the + * number of grid elements. For each different grid position a different index is returned. + */ + unsigned long GetIndexToPosition(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const; + /** Returns the grid position to the given index. If the index is equal to or higher than the + * number of grid elements false is returned and the triple is set to ULONG_MAX. + */ + bool GetPositionToIndex(unsigned long id, + unsigned long& ulX, + unsigned long& ulY, + unsigned long& ulZ) const; + /** Returns the number of elements in a given grid. */ + unsigned long GetCtElements(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const + { + return static_cast(_aulGrid[ulX][ulY][ulZ].size()); + } + /** Validates the grid structure and rebuilds it if needed. Must be implemented in sub-classes. + */ + virtual void Validate(const MeshKernel& rclM) = 0; + /** Verifies the grid structure and returns false if inconsistencies are found. */ + virtual bool Verify() const = 0; + /** Checks whether the point is inside the grid. In case it is inside true is returned with the + * grid position, otherwise false is returned and the grid position is undefined. + */ + bool CheckPosition(const Base::Vector3f& rclPoint, + unsigned long& rulX, + unsigned long& rulY, + unsigned long& rulZ) const; + /** Returns the indices of the grid this point lies in. If the point is outside the grid the + * indices of the nearest grid element are taken.*/ + virtual void Position(const Base::Vector3f& rclPoint, + unsigned long& rulX, + unsigned long& rulY, + unsigned long& rulZ) const; + /** Checks if this is a valid grid position. */ + inline bool CheckPos(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const; + /** Get the indices of all elements lying in the grids around a given grid with distance \a + * ulDistance. */ + void GetHull(unsigned long ulX, + unsigned long ulY, + unsigned long ulZ, + unsigned long ulDistance, + std::set& raclInd) const; protected: - /** Initializes the size of the internal structure. */ - virtual void InitGrid (); - /** Deletes the grid structure. */ - virtual void Clear (); - /** Calculates the grid length dependent on maximum number of grids. */ - virtual void CalculateGridLength (unsigned long ulCtGrid, unsigned long ulMaxGrids); - /** Calculates the grid length dependent on the number of grids per axis. */ - virtual void CalculateGridLength (int iCtGridPerAxis); - /** Rebuilds the grid structure. Must be implemented in sub-classes. */ - virtual void RebuildGrid () = 0; - /** Returns the number of stored elements. Must be implemented in sub-classes. */ - virtual unsigned long HasElements () const = 0; + /** Initializes the size of the internal structure. */ + virtual void InitGrid(); + /** Deletes the grid structure. */ + virtual void Clear(); + /** Calculates the grid length dependent on maximum number of grids. */ + virtual void CalculateGridLength(unsigned long ulCtGrid, unsigned long ulMaxGrids); + /** Calculates the grid length dependent on the number of grids per axis. */ + virtual void CalculateGridLength(int iCtGridPerAxis); + /** Rebuilds the grid structure. Must be implemented in sub-classes. */ + virtual void RebuildGrid() = 0; + /** Returns the number of stored elements. Must be implemented in sub-classes. */ + virtual unsigned long HasElements() const = 0; protected: - std::vector > > > _aulGrid; /**< Grid data structure. */ - const MeshKernel* _pclMesh; /**< The mesh kernel. */ - unsigned long _ulCtElements;/**< Number of grid elements for validation issues. */ - unsigned long _ulCtGridsX; /**< Number of grid elements in z. */ - unsigned long _ulCtGridsY; /**< Number of grid elements in z. */ - unsigned long _ulCtGridsZ; /**< Number of grid elements in z. */ - float _fGridLenX; /**< Length of grid elements in x. */ - float _fGridLenY; /**< Length of grid elements in y. */ - float _fGridLenZ; /**< Length of grid elements in z. */ - float _fMinX; /**< Grid null position in x. */ - float _fMinY; /**< Grid null position in y. */ - float _fMinZ; /**< Grid null position in z. */ + std::vector>>> + _aulGrid; /**< Grid data structure. */ + const MeshKernel* _pclMesh; /**< The mesh kernel. */ + unsigned long _ulCtElements; /**< Number of grid elements for validation issues. */ + unsigned long _ulCtGridsX; /**< Number of grid elements in z. */ + unsigned long _ulCtGridsY; /**< Number of grid elements in z. */ + unsigned long _ulCtGridsZ; /**< Number of grid elements in z. */ + float _fGridLenX; /**< Length of grid elements in x. */ + float _fGridLenY; /**< Length of grid elements in y. */ + float _fGridLenZ; /**< Length of grid elements in z. */ + float _fMinX; /**< Grid null position in x. */ + float _fMinY; /**< Grid null position in y. */ + float _fMinZ; /**< Grid null position in z. */ - // friends - friend class MeshGridIterator; + // friends + friend class MeshGridIterator; }; /** @@ -180,58 +220,79 @@ protected: class MeshExport MeshFacetGrid: public MeshGrid { public: - /** @name Construction */ - //@{ - /// Construction - explicit MeshFacetGrid (const MeshKernel &rclM); - /// Construction - MeshFacetGrid () : MeshGrid() { } - /// Construction - MeshFacetGrid (const MeshKernel &rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ); - /// Construction - MeshFacetGrid (const MeshKernel &rclM, int iCtGridPerAxis); - /// Construction - MeshFacetGrid (const MeshKernel &rclM, float fGridLen); - /// Destruction - ~MeshFacetGrid () override = default; - //@} + /** @name Construction */ + //@{ + /// Construction + explicit MeshFacetGrid(const MeshKernel& rclM); + /// Construction + MeshFacetGrid() + : MeshGrid() + {} + /// Construction + MeshFacetGrid(const MeshKernel& rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ); + /// Construction + MeshFacetGrid(const MeshKernel& rclM, int iCtGridPerAxis); + /// Construction + MeshFacetGrid(const MeshKernel& rclM, float fGridLen); + /// Destruction + ~MeshFacetGrid() override = default; + //@} - /** @name Search */ - //@{ - /** Searches for the nearest facet from a point. */ - unsigned long SearchNearestFromPoint (const Base::Vector3f &rclPt) const; - /** Searches for the nearest facet from a point with the maximum search area. */ - unsigned long SearchNearestFromPoint (const Base::Vector3f &rclPt, float fMaxSearchArea) const; - /** Searches for the nearest facet in a given grid element and returns the facet index and the actual distance. */ - void SearchNearestFacetInGrid(unsigned long ulX, unsigned long ulY, unsigned long ulZ, const Base::Vector3f &rclPt, - float &rfMinDist, ElementIndex &rulFacetInd) const; - /** Does basically the same as the method above unless that grid neighbours up to the order of \a ulDistance - * are introduced into the search. */ - void SearchNearestFacetInHull (unsigned long ulX, unsigned long ulY, unsigned long ulZ, unsigned long ulDistance, - const Base::Vector3f &rclPt, ElementIndex &rulFacetInd, float &rfMinDist) const; - //@} + /** @name Search */ + //@{ + /** Searches for the nearest facet from a point. */ + unsigned long SearchNearestFromPoint(const Base::Vector3f& rclPt) const; + /** Searches for the nearest facet from a point with the maximum search area. */ + unsigned long SearchNearestFromPoint(const Base::Vector3f& rclPt, float fMaxSearchArea) const; + /** Searches for the nearest facet in a given grid element and returns the facet index and the + * actual distance. */ + void SearchNearestFacetInGrid(unsigned long ulX, + unsigned long ulY, + unsigned long ulZ, + const Base::Vector3f& rclPt, + float& rfMinDist, + ElementIndex& rulFacetInd) const; + /** Does basically the same as the method above unless that grid neighbours up to the order of + * \a ulDistance are introduced into the search. */ + void SearchNearestFacetInHull(unsigned long ulX, + unsigned long ulY, + unsigned long ulZ, + unsigned long ulDistance, + const Base::Vector3f& rclPt, + ElementIndex& rulFacetInd, + float& rfMinDist) const; + //@} - /** Validates the grid structure and rebuilds it if needed. */ - void Validate (const MeshKernel &rclM) override; - /** Validates the grid structure and rebuilds it if needed. */ - virtual void Validate (); - /** Verifies the grid structure and returns false if inconsistencies are found. */ - bool Verify() const override; + /** Validates the grid structure and rebuilds it if needed. */ + void Validate(const MeshKernel& rclM) override; + /** Validates the grid structure and rebuilds it if needed. */ + virtual void Validate(); + /** Verifies the grid structure and returns false if inconsistencies are found. */ + bool Verify() const override; protected: - /** Returns the grid numbers to the given point \a rclPoint. */ - inline void Pos (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const; - /** Returns the grid numbers to the given point \a rclPoint. */ - inline void PosWithCheck (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const; - /** Adds a new facet element to the grid structure. \a rclFacet is the geometric facet and \a ulFacetIndex - * the corresponding index in the mesh kernel. The facet is added to each grid element that intersects - * the facet. */ - inline void AddFacet (const MeshGeomFacet &rclFacet, ElementIndex ulFacetIndex, float fEpsilon = 0.0f); - /** Returns the number of stored elements. */ - unsigned long HasElements () const override - { return _pclMesh->CountFacets(); } - /** Rebuilds the grid structure. */ - void RebuildGrid () override; + /** Returns the grid numbers to the given point \a rclPoint. */ + inline void Pos(const Base::Vector3f& rclPoint, + unsigned long& rulX, + unsigned long& rulY, + unsigned long& rulZ) const; + /** Returns the grid numbers to the given point \a rclPoint. */ + inline void PosWithCheck(const Base::Vector3f& rclPoint, + unsigned long& rulX, + unsigned long& rulY, + unsigned long& rulZ) const; + /** Adds a new facet element to the grid structure. \a rclFacet is the geometric facet and \a + * ulFacetIndex the corresponding index in the mesh kernel. The facet is added to each grid + * element that intersects the facet. */ + inline void + AddFacet(const MeshGeomFacet& rclFacet, ElementIndex ulFacetIndex, float fEpsilon = 0.0f); + /** Returns the number of stored elements. */ + unsigned long HasElements() const override + { + return _pclMesh->CountFacets(); + } + /** Rebuilds the grid structure. */ + void RebuildGrid() override; }; /** @@ -241,42 +302,48 @@ protected: class MeshExport MeshPointGrid: public MeshGrid { public: - /** @name Construction */ - //@{ - /// Construction - MeshPointGrid (); - /// Construction - explicit MeshPointGrid (const MeshKernel &rclM); - /// Construction - MeshPointGrid (const MeshKernel &rclM, int iCtGridPerAxis); - /// Construction - MeshPointGrid (const MeshKernel &rclM, float fGridLen); - /// Construction - MeshPointGrid (const MeshKernel &rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ); - /// Destruction - ~MeshPointGrid () override = default; - //@} + /** @name Construction */ + //@{ + /// Construction + MeshPointGrid(); + /// Construction + explicit MeshPointGrid(const MeshKernel& rclM); + /// Construction + MeshPointGrid(const MeshKernel& rclM, int iCtGridPerAxis); + /// Construction + MeshPointGrid(const MeshKernel& rclM, float fGridLen); + /// Construction + MeshPointGrid(const MeshKernel& rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ); + /// Destruction + ~MeshPointGrid() override = default; + //@} - /** Finds all points that lie in the same grid as the point \a rclPoint. */ - unsigned long FindElements(const Base::Vector3f &rclPoint, std::set& aulElements) const; - /** Validates the grid structure and rebuilds it if needed. */ - void Validate (const MeshKernel &rclM) override; - /** Validates the grid structure and rebuilds it if needed. */ - virtual void Validate (); - /** Verifies the grid structure and returns false if inconsistencies are found. */ - bool Verify() const override; + /** Finds all points that lie in the same grid as the point \a rclPoint. */ + unsigned long FindElements(const Base::Vector3f& rclPoint, + std::set& aulElements) const; + /** Validates the grid structure and rebuilds it if needed. */ + void Validate(const MeshKernel& rclM) override; + /** Validates the grid structure and rebuilds it if needed. */ + virtual void Validate(); + /** Verifies the grid structure and returns false if inconsistencies are found. */ + bool Verify() const override; protected: - /** Adds a new point element to the grid structure. \a rclPt is the geometric point and \a ulPtIndex - * the corresponding index in the mesh kernel. */ - void AddPoint (const MeshPoint &rclPt, ElementIndex ulPtIndex, float fEpsilon = 0.0f); - /** Returns the grid numbers to the given point \a rclPoint. */ - void Pos(const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const; - /** Returns the number of stored elements. */ - unsigned long HasElements () const override - { return _pclMesh->CountPoints(); } - /** Rebuilds the grid structure. */ - void RebuildGrid () override; + /** Adds a new point element to the grid structure. \a rclPt is the geometric point and \a + * ulPtIndex the corresponding index in the mesh kernel. */ + void AddPoint(const MeshPoint& rclPt, ElementIndex ulPtIndex, float fEpsilon = 0.0f); + /** Returns the grid numbers to the given point \a rclPoint. */ + void Pos(const Base::Vector3f& rclPoint, + unsigned long& rulX, + unsigned long& rulY, + unsigned long& rulZ) const; + /** Returns the number of stored elements. */ + unsigned long HasElements() const override + { + return _pclMesh->CountPoints(); + } + /** Rebuilds the grid structure. */ + void RebuildGrid() override; }; /** @@ -286,201 +353,255 @@ protected: class MeshExport MeshGridIterator { public: - /// Construction - explicit MeshGridIterator (const MeshGrid &rclG); - /** Returns the bounding box of the current grid element. */ - Base::BoundBox3f GetBoundBox () const - { return _rclGrid.GetBoundBox(_ulX, _ulY, _ulZ); } - /** Returns indices of the elements in the current grid. */ - void GetElements (std::vector &raulElements) const - { - raulElements.insert(raulElements.end(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end()); - } - /** Returns the number of elements in the current grid. */ - unsigned long GetCtElements() const - { - return _rclGrid.GetCtElements(_ulX, _ulY, _ulZ); - } - /** @name Iteration */ - //@{ - /** Sets the iterator to the first element*/ - void Init () - { _ulX = _ulY = _ulZ = 0; } - /** Checks if the iterator has not yet reached the end position. */ - bool More () const - { return (_ulZ < _rclGrid._ulCtGridsZ); } - /** Go to the next grid. */ - void Next () - { - if (++_ulX >= (_rclGrid._ulCtGridsX)) _ulX = 0; else return; - if (++_ulY >= (_rclGrid._ulCtGridsY)) { _ulY = 0; _ulZ++; } else return; - } - //@} + /// Construction + explicit MeshGridIterator(const MeshGrid& rclG); + /** Returns the bounding box of the current grid element. */ + Base::BoundBox3f GetBoundBox() const + { + return _rclGrid.GetBoundBox(_ulX, _ulY, _ulZ); + } + /** Returns indices of the elements in the current grid. */ + void GetElements(std::vector& raulElements) const + { + raulElements.insert(raulElements.end(), + _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), + _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end()); + } + /** Returns the number of elements in the current grid. */ + unsigned long GetCtElements() const + { + return _rclGrid.GetCtElements(_ulX, _ulY, _ulZ); + } + /** @name Iteration */ + //@{ + /** Sets the iterator to the first element*/ + void Init() + { + _ulX = _ulY = _ulZ = 0; + } + /** Checks if the iterator has not yet reached the end position. */ + bool More() const + { + return (_ulZ < _rclGrid._ulCtGridsZ); + } + /** Go to the next grid. */ + void Next() + { + if (++_ulX >= (_rclGrid._ulCtGridsX)) { + _ulX = 0; + } + else { + return; + } + if (++_ulY >= (_rclGrid._ulCtGridsY)) { + _ulY = 0; + _ulZ++; + } + else { + return; + } + } + //@} - /** @name Tests with rays */ - //@{ - /** Searches for facets around the ray. */ - bool InitOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, std::vector &raulElements); - /** Searches for facets around the ray. */ - bool InitOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, float fMaxSearchArea, std::vector &raulElements); - /** Searches for facets around the ray. */ - bool NextOnRay (std::vector &raulElements); - //@} + /** @name Tests with rays */ + //@{ + /** Searches for facets around the ray. */ + bool InitOnRay(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + std::vector& raulElements); + /** Searches for facets around the ray. */ + bool InitOnRay(const Base::Vector3f& rclPt, + const Base::Vector3f& rclDir, + float fMaxSearchArea, + std::vector& raulElements); + /** Searches for facets around the ray. */ + bool NextOnRay(std::vector& raulElements); + //@} - /** Returns the grid number of the current position. */ - void GetGridPos (unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const - { rulX = _ulX; rulY = _ulY; rulZ = _ulZ; } + /** Returns the grid number of the current position. */ + void GetGridPos(unsigned long& rulX, unsigned long& rulY, unsigned long& rulZ) const + { + rulX = _ulX; + rulY = _ulY; + rulZ = _ulZ; + } protected: - const MeshGrid& _rclGrid; /**< The mesh kernel. */ - unsigned long _ulX{0}; /**< Number of grids in x. */ - unsigned long _ulY{0}; /**< Number of grids in y. */ - unsigned long _ulZ{0}; /**< Number of grids in z. */ - Base::Vector3f _clPt; /**< Base point of search ray. */ - Base::Vector3f _clDir; /**< Direction of search ray. */ - bool _bValidRay{false}; /**< Search ray ok? */ - float _fMaxSearchArea{FLOAT_MAX}; - /** Checks if a grid position is already visited by NextOnRay(). */ - struct GridElement - { - GridElement( unsigned long x, unsigned long y, unsigned long z) - { this->x = x; this->y = y; this->z = z; } - bool operator < (const GridElement& pos) const + const MeshGrid& _rclGrid; /**< The mesh kernel. */ + unsigned long _ulX {0}; /**< Number of grids in x. */ + unsigned long _ulY {0}; /**< Number of grids in y. */ + unsigned long _ulZ {0}; /**< Number of grids in z. */ + Base::Vector3f _clPt; /**< Base point of search ray. */ + Base::Vector3f _clDir; /**< Direction of search ray. */ + bool _bValidRay {false}; /**< Search ray ok? */ + float _fMaxSearchArea {FLOAT_MAX}; + /** Checks if a grid position is already visited by NextOnRay(). */ + struct GridElement { - if ( x == pos.x) - { if ( y == pos.y) return z < pos.z; else return y < pos.y; } - else - { return x < pos.x; } - } - private: - unsigned long x,y,z; - }; - std::set _cSearchPositions; + GridElement(unsigned long x, unsigned long y, unsigned long z) + { + this->x = x; + this->y = y; + this->z = z; + } + bool operator<(const GridElement& pos) const + { + if (x == pos.x) { + if (y == pos.y) { + return z < pos.z; + } + else { + return y < pos.y; + } + } + else { + return x < pos.x; + } + } + + private: + unsigned long x, y, z; + }; + std::set _cSearchPositions; }; // -------------------------------------------------------------- -inline Base::BoundBox3f MeshGrid::GetBoundBox (unsigned long ulX, unsigned long ulY, unsigned long ulZ) const +inline Base::BoundBox3f +MeshGrid::GetBoundBox(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const { - float fX, fY, fZ; + float fX, fY, fZ; - fX = _fMinX + (float(ulX) * _fGridLenX); - fY = _fMinY + (float(ulY) * _fGridLenY); - fZ = _fMinZ + (float(ulZ) * _fGridLenZ); + fX = _fMinX + (float(ulX) * _fGridLenX); + fY = _fMinY + (float(ulY) * _fGridLenY); + fZ = _fMinZ + (float(ulZ) * _fGridLenZ); - return Base::BoundBox3f(fX, fY, fZ, fX + _fGridLenX, fY + _fGridLenY, fZ + _fGridLenZ); + return Base::BoundBox3f(fX, fY, fZ, fX + _fGridLenX, fY + _fGridLenY, fZ + _fGridLenZ); } -inline Base::BoundBox3f MeshGrid::GetBoundBox () const +inline Base::BoundBox3f MeshGrid::GetBoundBox() const { - return Base::BoundBox3f(_fMinX, _fMinY, _fMinZ, _fMinX + (_fGridLenX * float(_ulCtGridsX)), - _fMinY + (_fGridLenY * float(_ulCtGridsY)), _fMinZ + (_fGridLenZ * float(_ulCtGridsZ))); + return Base::BoundBox3f(_fMinX, + _fMinY, + _fMinZ, + _fMinX + (_fGridLenX * float(_ulCtGridsX)), + _fMinY + (_fGridLenY * float(_ulCtGridsY)), + _fMinZ + (_fGridLenZ * float(_ulCtGridsZ))); } -inline Base::BoundBox3f MeshGrid::GetMeshBoundBox () const +inline Base::BoundBox3f MeshGrid::GetMeshBoundBox() const { - Base::BoundBox3f clBBenlarged = _pclMesh->GetBoundBox(); - clBBenlarged.Enlarge(MESHGRID_BBOX_EXTENSION); + Base::BoundBox3f clBBenlarged = _pclMesh->GetBoundBox(); + clBBenlarged.Enlarge(MESHGRID_BBOX_EXTENSION); - return clBBenlarged; + return clBBenlarged; } -inline bool MeshGrid::CheckPos (unsigned long ulX, unsigned long ulY, unsigned long ulZ) const +inline bool MeshGrid::CheckPos(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const { - return ((ulX < _ulCtGridsX) && (ulY < _ulCtGridsY) && (ulZ < _ulCtGridsZ)); + return ((ulX < _ulCtGridsX) && (ulY < _ulCtGridsY) && (ulZ < _ulCtGridsZ)); } // -------------------------------------------------------------- -inline void MeshFacetGrid::Pos (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const +inline void MeshFacetGrid::Pos(const Base::Vector3f& rclPoint, + unsigned long& rulX, + unsigned long& rulY, + unsigned long& rulZ) const { - rulX = static_cast((rclPoint.x - _fMinX) / _fGridLenX); - rulY = static_cast((rclPoint.y - _fMinY) / _fGridLenY); - rulZ = static_cast((rclPoint.z - _fMinZ) / _fGridLenZ); - - assert((rulX < _ulCtGridsX) && (rulY < _ulCtGridsY) && (rulZ < _ulCtGridsZ)); -} - -inline void MeshFacetGrid::PosWithCheck (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const -{ - if ( rclPoint.x < _fMinX) - rulX = 0; - else - { rulX = static_cast((rclPoint.x - _fMinX) / _fGridLenX); - if (rulX >= _ulCtGridsX) - rulX = (_ulCtGridsX-1); - } - - if ( rclPoint.y < _fMinY) - rulY = 0; - else - { rulY = static_cast((rclPoint.y - _fMinY) / _fGridLenY); - if (rulY >= _ulCtGridsY) - rulY = (_ulCtGridsY-1); - } - - if ( rclPoint.z < _fMinZ) - rulZ = 0; - else - { rulZ = static_cast((rclPoint.z - _fMinZ) / _fGridLenZ); - if (rulZ >= _ulCtGridsZ) - rulZ = (_ulCtGridsZ-1); - } - assert((rulX < _ulCtGridsX) && (rulY < _ulCtGridsY) && (rulZ < _ulCtGridsZ)); + assert((rulX < _ulCtGridsX) && (rulY < _ulCtGridsY) && (rulZ < _ulCtGridsZ)); } -inline void MeshFacetGrid::AddFacet (const MeshGeomFacet &rclFacet, ElementIndex ulFacetIndex, float /*fEpsilon*/) +inline void MeshFacetGrid::PosWithCheck(const Base::Vector3f& rclPoint, + unsigned long& rulX, + unsigned long& rulY, + unsigned long& rulZ) const { - unsigned long ulX, ulY, ulZ; - - unsigned long ulX1, ulY1, ulZ1, ulX2, ulY2, ulZ2; - - Base::BoundBox3f clBB; - - clBB.Add(rclFacet._aclPoints[0]); - clBB.Add(rclFacet._aclPoints[1]); - clBB.Add(rclFacet._aclPoints[2]); - - //float fDiagonalLength = clBB.CalcDiagonalLength(); - - //clBB.Enlarge(fEpsilon*fDiagonalLength); - - Pos(Base::Vector3f(clBB.MinX,clBB.MinY,clBB.MinZ), ulX1, ulY1, ulZ1); - Pos(Base::Vector3f(clBB.MaxX,clBB.MaxY,clBB.MaxZ), ulX2, ulY2, ulZ2); - - /* - if (ulX1 > 0) ulX1--; - if (ulY1 > 0) ulY1--; - if (ulZ1 > 0) ulZ1--; - - if (ulX2 < (_ulCtGridsX-1)) ulX2++; - if (ulY2 < (_ulCtGridsY-1)) ulY2++; - if (ulZ2 < (_ulCtGridsZ-1)) ulZ2++; - */ - - // falls Facet ueber mehrere BB reicht - if ((ulX1 < ulX2) || (ulY1 < ulY2) || (ulZ1 < ulZ2)) - { - for (ulX = ulX1; ulX <= ulX2; ulX++) - { - for (ulY = ulY1; ulY <= ulY2; ulY++) - { - for (ulZ = ulZ1; ulZ <= ulZ2; ulZ++) - { - if ( rclFacet.IntersectBoundingBox( GetBoundBox(ulX, ulY, ulZ) ) ) - _aulGrid[ulX][ulY][ulZ].insert(ulFacetIndex); - } - } + if (rclPoint.x < _fMinX) { + rulX = 0; } - } - else - _aulGrid[ulX1][ulY1][ulZ1].insert(ulFacetIndex); + else { + rulX = static_cast((rclPoint.x - _fMinX) / _fGridLenX); + if (rulX >= _ulCtGridsX) { + rulX = (_ulCtGridsX - 1); + } + } + + if (rclPoint.y < _fMinY) { + rulY = 0; + } + else { + rulY = static_cast((rclPoint.y - _fMinY) / _fGridLenY); + if (rulY >= _ulCtGridsY) { + rulY = (_ulCtGridsY - 1); + } + } + + if (rclPoint.z < _fMinZ) { + rulZ = 0; + } + else { + rulZ = static_cast((rclPoint.z - _fMinZ) / _fGridLenZ); + if (rulZ >= _ulCtGridsZ) { + rulZ = (_ulCtGridsZ - 1); + } + } + + assert((rulX < _ulCtGridsX) && (rulY < _ulCtGridsY) && (rulZ < _ulCtGridsZ)); } -} // namespace MeshCore +inline void MeshFacetGrid::AddFacet(const MeshGeomFacet& rclFacet, + ElementIndex ulFacetIndex, + float /*fEpsilon*/) +{ + unsigned long ulX, ulY, ulZ; -#endif // MESH_GRID_H + unsigned long ulX1, ulY1, ulZ1, ulX2, ulY2, ulZ2; + + Base::BoundBox3f clBB; + + clBB.Add(rclFacet._aclPoints[0]); + clBB.Add(rclFacet._aclPoints[1]); + clBB.Add(rclFacet._aclPoints[2]); + + // float fDiagonalLength = clBB.CalcDiagonalLength(); + + // clBB.Enlarge(fEpsilon*fDiagonalLength); + + Pos(Base::Vector3f(clBB.MinX, clBB.MinY, clBB.MinZ), ulX1, ulY1, ulZ1); + Pos(Base::Vector3f(clBB.MaxX, clBB.MaxY, clBB.MaxZ), ulX2, ulY2, ulZ2); + + /* + if (ulX1 > 0) ulX1--; + if (ulY1 > 0) ulY1--; + if (ulZ1 > 0) ulZ1--; + + if (ulX2 < (_ulCtGridsX-1)) ulX2++; + if (ulY2 < (_ulCtGridsY-1)) ulY2++; + if (ulZ2 < (_ulCtGridsZ-1)) ulZ2++; + */ + + // falls Facet ueber mehrere BB reicht + if ((ulX1 < ulX2) || (ulY1 < ulY2) || (ulZ1 < ulZ2)) { + for (ulX = ulX1; ulX <= ulX2; ulX++) { + for (ulY = ulY1; ulY <= ulY2; ulY++) { + for (ulZ = ulZ1; ulZ <= ulZ2; ulZ++) { + if (rclFacet.IntersectBoundingBox(GetBoundBox(ulX, ulY, ulZ))) { + _aulGrid[ulX][ulY][ulZ].insert(ulFacetIndex); + } + } + } + } + } + else { + _aulGrid[ulX1][ulY1][ulZ1].insert(ulFacetIndex); + } +} + +} // namespace MeshCore + +#endif // MESH_GRID_H diff --git a/src/Mod/Mesh/App/Core/Helpers.h b/src/Mod/Mesh/App/Core/Helpers.h index b5dbc4390b..0e7ab2f5bc 100644 --- a/src/Mod/Mesh/App/Core/Helpers.h +++ b/src/Mod/Mesh/App/Core/Helpers.h @@ -26,26 +26,31 @@ #include "Elements.h" -namespace MeshCore { +namespace MeshCore +{ /** * Helper class for points. */ struct MeshExport MeshHelpPoint { - inline void Set (FacetIndex ulCorner, FacetIndex ulFacet, const Base::Vector3f &rclPt); + inline void Set(FacetIndex ulCorner, FacetIndex ulFacet, const Base::Vector3f& rclPt); - inline bool operator < (const MeshHelpPoint &rclObj) const; - inline bool operator == (const MeshHelpPoint &rclObj) const; + inline bool operator<(const MeshHelpPoint& rclObj) const; + inline bool operator==(const MeshHelpPoint& rclObj) const; - FacetIndex Index () const - { return _ulInd >> 2; } + FacetIndex Index() const + { + return _ulInd >> 2; + } - FacetIndex Corner () const - { return _ulInd & 3; } + FacetIndex Corner() const + { + return _ulInd & 3; + } - MeshPoint _clPt; - FacetIndex _ulInd; + MeshPoint _clPt; + FacetIndex _ulInd; }; /** @@ -53,7 +58,7 @@ struct MeshExport MeshHelpPoint */ struct MeshPointBuilder: public std::vector { - inline void Add (FacetIndex ulCorner, FacetIndex ulFacet, const Base::Vector3f &rclPt); + inline void Add(FacetIndex ulCorner, FacetIndex ulFacet, const Base::Vector3f& rclPt); }; /** @@ -61,24 +66,27 @@ struct MeshPointBuilder: public std::vector */ struct MeshExport MeshHelpBuilderEdge { - FacetIndex Side () const - { return _ulFIndex & 3; } + FacetIndex Side() const + { + return _ulFIndex & 3; + } - FacetIndex Index () const - { return _ulFIndex >> 2; } + FacetIndex Index() const + { + return _ulFIndex >> 2; + } - inline void Set (PointIndex ulInd1, PointIndex ulInd2, - FacetIndex ulSide, FacetIndex ulFInd); + inline void Set(PointIndex ulInd1, PointIndex ulInd2, FacetIndex ulSide, FacetIndex ulFInd); - inline bool operator < (const MeshHelpBuilderEdge &rclObj) const; + inline bool operator<(const MeshHelpBuilderEdge& rclObj) const; - inline bool operator == (const MeshHelpBuilderEdge &rclObj) const; + inline bool operator==(const MeshHelpBuilderEdge& rclObj) const; - inline bool operator != (const MeshHelpBuilderEdge &rclObj) const; + inline bool operator!=(const MeshHelpBuilderEdge& rclObj) const; - FacetIndex _ulFIndex; // facet index - PointIndex _aulInd[2]; // point index + FacetIndex _ulFIndex; // facet index + PointIndex _aulInd[2]; // point index }; /** @@ -86,84 +94,87 @@ struct MeshExport MeshHelpBuilderEdge */ struct MeshEdgeBuilder: public std::vector { - using _TIterator = std::vector::iterator; - inline void Add (PointIndex ulInd1, PointIndex ulInd2, FacetIndex ulSide, FacetIndex ulFInd); + using _TIterator = std::vector::iterator; + inline void Add(PointIndex ulInd1, PointIndex ulInd2, FacetIndex ulSide, FacetIndex ulFInd); }; -inline void MeshHelpPoint::Set (FacetIndex ulCorner, FacetIndex ulFacet, const Base::Vector3f &rclPt) +inline void MeshHelpPoint::Set(FacetIndex ulCorner, FacetIndex ulFacet, const Base::Vector3f& rclPt) { - _ulInd = (ulFacet << 2) | ulCorner; - _clPt = rclPt; + _ulInd = (ulFacet << 2) | ulCorner; + _clPt = rclPt; } -inline bool MeshHelpPoint::operator < (const MeshHelpPoint &rclObj) const +inline bool MeshHelpPoint::operator<(const MeshHelpPoint& rclObj) const { - if (_clPt.x == rclObj._clPt.x) - { - if (_clPt.y == rclObj._clPt.y) - return _clPt.z < rclObj._clPt.z; - else - return _clPt.y < rclObj._clPt.y; - } - else - return _clPt.x < rclObj._clPt.x; + if (_clPt.x == rclObj._clPt.x) { + if (_clPt.y == rclObj._clPt.y) { + return _clPt.z < rclObj._clPt.z; + } + else { + return _clPt.y < rclObj._clPt.y; + } + } + else { + return _clPt.x < rclObj._clPt.x; + } } -inline bool MeshHelpPoint::operator == (const MeshHelpPoint &rclObj) const +inline bool MeshHelpPoint::operator==(const MeshHelpPoint& rclObj) const { - return Base::DistanceP2(_clPt, rclObj._clPt) < MeshDefinitions::_fMinPointDistanceP2; + return Base::DistanceP2(_clPt, rclObj._clPt) < MeshDefinitions::_fMinPointDistanceP2; } -inline void MeshPointBuilder::Add (FacetIndex ulCorner, FacetIndex ulFacet, const Base::Vector3f &rclPt) +inline void +MeshPointBuilder::Add(FacetIndex ulCorner, FacetIndex ulFacet, const Base::Vector3f& rclPt) { - MeshHelpPoint clObj; - clObj.Set(ulCorner, ulFacet, rclPt); - push_back(clObj); + MeshHelpPoint clObj; + clObj.Set(ulCorner, ulFacet, rclPt); + push_back(clObj); } -inline void MeshHelpBuilderEdge::Set (PointIndex ulInd1, PointIndex ulInd2, - FacetIndex ulSide, FacetIndex ulFInd) +inline void +MeshHelpBuilderEdge::Set(PointIndex ulInd1, PointIndex ulInd2, FacetIndex ulSide, FacetIndex ulFInd) { - if (ulInd1 < ulInd2) - { - _aulInd[0] = ulInd1; - _aulInd[1] = ulInd2; - } - else - { - _aulInd[0] = ulInd2; - _aulInd[1] = ulInd1; - } - _ulFIndex = (ulFInd << 2) | ulSide; + if (ulInd1 < ulInd2) { + _aulInd[0] = ulInd1; + _aulInd[1] = ulInd2; + } + else { + _aulInd[0] = ulInd2; + _aulInd[1] = ulInd1; + } + _ulFIndex = (ulFInd << 2) | ulSide; } -inline bool MeshHelpBuilderEdge::operator < (const MeshHelpBuilderEdge &rclObj) const +inline bool MeshHelpBuilderEdge::operator<(const MeshHelpBuilderEdge& rclObj) const { - if (_aulInd[0] == rclObj._aulInd[0]) - return _aulInd[1] < rclObj._aulInd[1]; - else - return _aulInd[0] < rclObj._aulInd[0]; + if (_aulInd[0] == rclObj._aulInd[0]) { + return _aulInd[1] < rclObj._aulInd[1]; + } + else { + return _aulInd[0] < rclObj._aulInd[0]; + } } -inline bool MeshHelpBuilderEdge::operator == (const MeshHelpBuilderEdge &rclObj) const +inline bool MeshHelpBuilderEdge::operator==(const MeshHelpBuilderEdge& rclObj) const { - return (_aulInd[0] == rclObj._aulInd[0]) && (_aulInd[1] == rclObj._aulInd[1]); + return (_aulInd[0] == rclObj._aulInd[0]) && (_aulInd[1] == rclObj._aulInd[1]); } -inline bool MeshHelpBuilderEdge::operator != (const MeshHelpBuilderEdge &rclObj) const +inline bool MeshHelpBuilderEdge::operator!=(const MeshHelpBuilderEdge& rclObj) const { - return (_aulInd[0] != rclObj._aulInd[0]) || (_aulInd[1] != rclObj._aulInd[1]); + return (_aulInd[0] != rclObj._aulInd[0]) || (_aulInd[1] != rclObj._aulInd[1]); } -inline void MeshEdgeBuilder::Add (PointIndex ulInd1, PointIndex ulInd2, - FacetIndex ulSide, FacetIndex ulFInd) +inline void +MeshEdgeBuilder::Add(PointIndex ulInd1, PointIndex ulInd2, FacetIndex ulSide, FacetIndex ulFInd) { - MeshHelpBuilderEdge clObj; - clObj.Set(ulInd1, ulInd2, ulSide, ulFInd); - push_back(clObj); + MeshHelpBuilderEdge clObj; + clObj.Set(ulInd1, ulInd2, ulSide, ulFInd); + push_back(clObj); } -} // namespace MeshCore +} // namespace MeshCore -#endif // MESH_HELPERS_H +#endif // MESH_HELPERS_H diff --git a/src/Mod/Mesh/App/Core/IO/Reader3MF.cpp b/src/Mod/Mesh/App/Core/IO/Reader3MF.cpp index 5dbe53dbb5..eeb595cd76 100644 --- a/src/Mod/Mesh/App/Core/IO/Reader3MF.cpp +++ b/src/Mod/Mesh/App/Core/IO/Reader3MF.cpp @@ -22,19 +22,19 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include +#include #endif +#include "Core/MeshIO.h" +#include "Core/MeshKernel.h" #include #include #include -#include "Core/MeshIO.h" -#include "Core/MeshKernel.h" #include #include "Reader3MF.h" @@ -43,7 +43,7 @@ using namespace MeshCore; XERCES_CPP_NAMESPACE_USE -Reader3MF::Reader3MF(std::istream &str) +Reader3MF::Reader3MF(std::istream& str) { zipios::ZipHeader zipHeader(str); if (zipHeader.isValid()) { @@ -51,7 +51,7 @@ Reader3MF::Reader3MF(std::istream &str) } } -Reader3MF::Reader3MF(const std::string &filename) +Reader3MF::Reader3MF(const std::string& filename) { zipios::ZipFile zipFile(filename); if (zipFile.isValid()) { @@ -73,8 +73,9 @@ std::vector Reader3MF::GetMeshIds() const bool Reader3MF::Load() { try { - if (!zip) + if (!zip) { return false; + } return LoadModel(*zip); } catch (const std::exception&) { @@ -107,12 +108,14 @@ bool Reader3MF::LoadModel(std::istream& str) bool Reader3MF::LoadModel(DOMDocument& xmlDocument) { - DOMNodeList *nodes = xmlDocument.getElementsByTagName(XStr("model").unicodeForm()); + DOMNodeList* nodes = xmlDocument.getElementsByTagName(XStr("model").unicodeForm()); for (XMLSize_t i = 0; i < nodes->getLength(); i++) { DOMNode* node = nodes->item(i); if (node->getNodeType() == DOMNode::ELEMENT_NODE) { - bool resource = LoadResources(static_cast(node)->getElementsByTagName(XStr("resources").unicodeForm())); - bool build = LoadBuild(static_cast(node)->getElementsByTagName(XStr("build").unicodeForm())); + bool resource = LoadResources(static_cast(node)->getElementsByTagName( + XStr("resources").unicodeForm())); + bool build = LoadBuild( + static_cast(node)->getElementsByTagName(XStr("build").unicodeForm())); return (resource && build); } } @@ -122,13 +125,15 @@ bool Reader3MF::LoadModel(DOMDocument& xmlDocument) bool Reader3MF::LoadResources(DOMNodeList* nodes) { - if (!nodes) + if (!nodes) { return false; + } for (XMLSize_t i = 0; i < nodes->getLength(); i++) { DOMNode* node = nodes->item(i); if (node->getNodeType() == DOMNode::ELEMENT_NODE) { - DOMNodeList *objectList = static_cast(node)->getElementsByTagName(XStr("object").unicodeForm()); + DOMNodeList* objectList = + static_cast(node)->getElementsByTagName(XStr("object").unicodeForm()); return LoadObjects(objectList); } } @@ -138,13 +143,15 @@ bool Reader3MF::LoadResources(DOMNodeList* nodes) bool Reader3MF::LoadBuild(XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* nodes) { - if (!nodes) + if (!nodes) { return false; + } for (XMLSize_t i = 0; i < nodes->getLength(); i++) { DOMNode* node = nodes->item(i); if (node->getNodeType() == DOMNode::ELEMENT_NODE) { - DOMNodeList *objectList = static_cast(node)->getElementsByTagName(XStr("item").unicodeForm()); + DOMNodeList* objectList = + static_cast(node)->getElementsByTagName(XStr("item").unicodeForm()); return LoadItems(objectList); } } @@ -155,8 +162,9 @@ bool Reader3MF::LoadBuild(XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* nodes) bool Reader3MF::LoadItems(XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* nodes) { const std::size_t numEntries = 12; - if (!nodes) + if (!nodes) { return false; + } for (XMLSize_t i = 0; i < nodes->getLength(); i++) { DOMNode* itemNode = nodes->item(i); @@ -166,11 +174,12 @@ bool Reader3MF::LoadItems(XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* nodes) int idValue = std::stoi(id); Base::Matrix4D mat; - DOMNode* transformAttr = itemNode->getAttributes()->getNamedItem(XStr("transform").unicodeForm()); + DOMNode* transformAttr = + itemNode->getAttributes()->getNamedItem(XStr("transform").unicodeForm()); if (transformAttr) { std::string transform = StrX(transformAttr->getNodeValue()).c_str(); boost::char_separator sep(" ,"); - boost::tokenizer > tokens(transform, sep); + boost::tokenizer> tokens(transform, sep); std::vector token_results; token_results.assign(tokens.begin(), tokens.end()); if (token_results.size() == numEntries) { @@ -202,8 +211,9 @@ bool Reader3MF::LoadItems(XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* nodes) bool Reader3MF::LoadObjects(XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* nodes) { - if (!nodes) + if (!nodes) { return false; + } for (XMLSize_t i = 0; i < nodes->getLength(); i++) { DOMNode* objectNode = nodes->item(i); @@ -211,7 +221,8 @@ bool Reader3MF::LoadObjects(XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* nodes) DOMNode* idAttr = objectNode->getAttributes()->getNamedItem(XStr("id").unicodeForm()); if (idAttr) { int id = std::stoi(StrX(idAttr->getNodeValue()).c_str()); - DOMNodeList *meshList = static_cast(objectNode)->getElementsByTagName(XStr("mesh").unicodeForm()); + DOMNodeList* meshList = static_cast(objectNode) + ->getElementsByTagName(XStr("mesh").unicodeForm()); LoadMesh(meshList, id); } } @@ -222,16 +233,21 @@ bool Reader3MF::LoadObjects(XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* nodes) void Reader3MF::LoadMesh(XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* nodes, int id) { - if (!nodes) + if (!nodes) { return; + } for (XMLSize_t i = 0; i < nodes->getLength(); i++) { DOMNode* node = nodes->item(i); if (node->getNodeType() == DOMNode::ELEMENT_NODE) { MeshPointArray points; MeshFacetArray facets; - LoadVertices(static_cast(node)->getElementsByTagName(XStr("vertices").unicodeForm()), points); - LoadTriangles(static_cast(node)->getElementsByTagName(XStr("triangles").unicodeForm()), facets); + LoadVertices(static_cast(node)->getElementsByTagName( + XStr("vertices").unicodeForm()), + points); + LoadTriangles(static_cast(node)->getElementsByTagName( + XStr("triangles").unicodeForm()), + facets); MeshCleanup meshCleanup(points, facets); meshCleanup.RemoveInvalids(); @@ -245,15 +261,18 @@ void Reader3MF::LoadMesh(XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* nodes, int } } -void Reader3MF::LoadVertices(XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* nodes, MeshPointArray& points) +void Reader3MF::LoadVertices(XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* nodes, + MeshPointArray& points) { - if (!nodes) + if (!nodes) { return; + } for (XMLSize_t i = 0; i < nodes->getLength(); i++) { DOMNode* node = nodes->item(i); if (node->getNodeType() == DOMNode::ELEMENT_NODE) { - DOMNodeList *vertexList = static_cast(node)->getElementsByTagName(XStr("vertex").unicodeForm()); + DOMNodeList* vertexList = + static_cast(node)->getElementsByTagName(XStr("vertex").unicodeForm()); if (vertexList) { XMLSize_t numVertices = vertexList->getLength(); points.reserve(numVertices); @@ -277,15 +296,18 @@ void Reader3MF::LoadVertices(XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* nodes, } } -void Reader3MF::LoadTriangles(XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* nodes, MeshFacetArray& facets) +void Reader3MF::LoadTriangles(XERCES_CPP_NAMESPACE_QUALIFIER DOMNodeList* nodes, + MeshFacetArray& facets) { - if (!nodes) + if (!nodes) { return; + } for (XMLSize_t i = 0; i < nodes->getLength(); i++) { DOMNode* node = nodes->item(i); if (node->getNodeType() == DOMNode::ELEMENT_NODE) { - DOMNodeList *triangleList = static_cast(node)->getElementsByTagName(XStr("triangle").unicodeForm()); + DOMNodeList* triangleList = static_cast(node)->getElementsByTagName( + XStr("triangle").unicodeForm()); if (triangleList) { XMLSize_t numTriangles = triangleList->getLength(); facets.reserve(numTriangles); diff --git a/src/Mod/Mesh/App/Core/IO/Reader3MF.h b/src/Mod/Mesh/App/Core/IO/Reader3MF.h index 439e70de10..93c705b940 100644 --- a/src/Mod/Mesh/App/Core/IO/Reader3MF.h +++ b/src/Mod/Mesh/App/Core/IO/Reader3MF.h @@ -24,12 +24,12 @@ #ifndef MESH_IO_READER_3MF_H #define MESH_IO_READER_3MF_H +#include +#include #include #include #include #include -#include -#include XERCES_CPP_NAMESPACE_BEGIN class DOMDocument; @@ -49,7 +49,7 @@ public: * * Passes an input stream to the constructor. */ - explicit Reader3MF(std::istream &str); + explicit Reader3MF(std::istream& str); /*! * \brief Reader3MF @@ -57,17 +57,19 @@ public: * * Passes a file name to the constructor */ - explicit Reader3MF(const std::string &filename); + explicit Reader3MF(const std::string& filename); /*! * \brief Load the mesh from the input stream or file * \return true on success and false otherwise */ bool Load(); std::vector GetMeshIds() const; - const MeshKernel& GetMesh(int id) const { + const MeshKernel& GetMesh(int id) const + { return meshes.at(id).first; } - const Base::Matrix4D& GetTransform(int id) const { + const Base::Matrix4D& GetTransform(int id) const + { return meshes.at(id).second; } @@ -88,7 +90,7 @@ private: std::unique_ptr zip; }; -} // namespace MeshCore +} // namespace MeshCore #endif // MESH_IO_READER_3MF_H diff --git a/src/Mod/Mesh/App/Core/IO/ReaderOBJ.cpp b/src/Mod/Mesh/App/Core/IO/ReaderOBJ.cpp index a601a4025b..706442f87c 100644 --- a/src/Mod/Mesh/App/Core/IO/ReaderOBJ.cpp +++ b/src/Mod/Mesh/App/Core/IO/ReaderOBJ.cpp @@ -22,15 +22,15 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include -# include +#include +#include +#include +#include #endif -#include #include "Core/MeshIO.h" #include "Core/MeshKernel.h" +#include #include "ReaderOBJ.h" @@ -38,53 +38,54 @@ using namespace MeshCore; ReaderOBJ::ReaderOBJ(MeshKernel& kernel, Material* material) - : _kernel(kernel) - , _material(material) -{ -} + : _kernel(kernel) + , _material(material) +{} -bool ReaderOBJ::Load(std::istream &str) +bool ReaderOBJ::Load(std::istream& str) { boost::regex rx_m("^mtllib\\s+(.+)\\s*$"); boost::regex rx_u(R"(^usemtl\s+([\x21-\x7E]+)\s*$)"); boost::regex rx_g(R"(^g\s+([\x21-\x7E]+)\s*$)"); boost::regex rx_p("^v\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" - "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" - "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)\\s*$"); + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)\\s*$"); boost::regex rx_c("^v\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" - "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" - "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" - "\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s*$"); + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" + "\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s*$"); boost::regex rx_t("^v\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" - "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" - "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" - "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" - "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" - "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)\\s*$"); + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)\\s*$"); boost::regex rx_f3("^f\\s+([-+]?[0-9]+)/?[-+]?[0-9]*/?[-+]?[0-9]*" - "\\s+([-+]?[0-9]+)/?[-+]?[0-9]*/?[-+]?[0-9]*" - "\\s+([-+]?[0-9]+)/?[-+]?[0-9]*/?[-+]?[0-9]*\\s*$"); + "\\s+([-+]?[0-9]+)/?[-+]?[0-9]*/?[-+]?[0-9]*" + "\\s+([-+]?[0-9]+)/?[-+]?[0-9]*/?[-+]?[0-9]*\\s*$"); boost::regex rx_f4("^f\\s+([-+]?[0-9]+)/?[-+]?[0-9]*/?[-+]?[0-9]*" - "\\s+([-+]?[0-9]+)/?[-+]?[0-9]*/?[-+]?[0-9]*" - "\\s+([-+]?[0-9]+)/?[-+]?[0-9]*/?[-+]?[0-9]*" - "\\s+([-+]?[0-9]+)/?[-+]?[0-9]*/?[-+]?[0-9]*\\s*$"); + "\\s+([-+]?[0-9]+)/?[-+]?[0-9]*/?[-+]?[0-9]*" + "\\s+([-+]?[0-9]+)/?[-+]?[0-9]*/?[-+]?[0-9]*" + "\\s+([-+]?[0-9]+)/?[-+]?[0-9]*/?[-+]?[0-9]*\\s*$"); boost::cmatch what; - unsigned long segment=0; + unsigned long segment = 0; MeshPointArray meshPoints; MeshFacetArray meshFacets; std::string line; float fX, fY, fZ; - int i1=1, i2=1, i3=1, i4=1; + int i1 = 1, i2 = 1, i3 = 1, i4 = 1; MeshFacet item; - if (!str || str.bad()) + if (!str || str.bad()) { return false; + } std::streambuf* buf = str.rdbuf(); - if (!buf) + if (!buf) { return false; + } MeshIO::Binding rgb_value = MeshIO::OVERALL; bool new_segment = true; @@ -108,7 +109,7 @@ bool ReaderOBJ::Load(std::istream &str) float b = std::min(std::atof(what[12].first), 255) / 255.0f; meshPoints.push_back(MeshPoint(Base::Vector3f(fX, fY, fZ))); - App::Color c(r,g,b); + App::Color c(r, g, b); unsigned long prop = static_cast(c.getPackedValue()); meshPoints.back().SetProperty(prop); rgb_value = MeshIO::PER_VERTEX; @@ -122,7 +123,7 @@ bool ReaderOBJ::Load(std::istream &str) float b = static_cast(std::atof(what[16].first)); meshPoints.push_back(MeshPoint(Base::Vector3f(fX, fY, fZ))); - App::Color c(r,g,b); + App::Color c(r, g, b); unsigned long prop = static_cast(c.getPackedValue()); meshPoints.back().SetProperty(prop); rgb_value = MeshIO::PER_VERTEX; @@ -132,8 +133,9 @@ bool ReaderOBJ::Load(std::istream &str) groupName = Base::Tools::escapedUnicodeToUtf8(what[1].first); } else if (boost::regex_match(line.c_str(), what, rx_m)) { - if (_material) + if (_material) { _material->library = Base::Tools::escapedUnicodeToUtf8(what[1].first); + } } else if (boost::regex_match(line.c_str(), what, rx_u)) { if (!materialName.empty()) { @@ -155,12 +157,12 @@ bool ReaderOBJ::Load(std::istream &str) // 3-vertex face i1 = std::atoi(what[1].first); - i1 = i1 > 0 ? i1-1 : i1+static_cast(meshPoints.size()); + i1 = i1 > 0 ? i1 - 1 : i1 + static_cast(meshPoints.size()); i2 = std::atoi(what[2].first); - i2 = i2 > 0 ? i2-1 : i2+static_cast(meshPoints.size()); + i2 = i2 > 0 ? i2 - 1 : i2 + static_cast(meshPoints.size()); i3 = std::atoi(what[3].first); - i3 = i3 > 0 ? i3-1 : i3+static_cast(meshPoints.size()); - item.SetVertices(i1,i2,i3); + i3 = i3 > 0 ? i3 - 1 : i3 + static_cast(meshPoints.size()); + item.SetVertices(i1, i2, i3); item.SetProperty(segment); meshFacets.push_back(item); countMaterialFacets++; @@ -178,20 +180,20 @@ bool ReaderOBJ::Load(std::istream &str) // 4-vertex face i1 = std::atoi(what[1].first); - i1 = i1 > 0 ? i1-1 : i1+static_cast(meshPoints.size()); + i1 = i1 > 0 ? i1 - 1 : i1 + static_cast(meshPoints.size()); i2 = std::atoi(what[2].first); - i2 = i2 > 0 ? i2-1 : i2+static_cast(meshPoints.size()); + i2 = i2 > 0 ? i2 - 1 : i2 + static_cast(meshPoints.size()); i3 = std::atoi(what[3].first); - i3 = i3 > 0 ? i3-1 : i3+static_cast(meshPoints.size()); + i3 = i3 > 0 ? i3 - 1 : i3 + static_cast(meshPoints.size()); i4 = std::atoi(what[4].first); - i4 = i4 > 0 ? i4-1 : i4+static_cast(meshPoints.size()); + i4 = i4 > 0 ? i4 - 1 : i4 + static_cast(meshPoints.size()); - item.SetVertices(i1,i2,i3); + item.SetVertices(i1, i2, i3); item.SetProperty(segment); meshFacets.push_back(item); countMaterialFacets++; - item.SetVertices(i3,i4,i1); + item.SetVertices(i3, i4, i1); item.SetProperty(segment); meshFacets.push_back(item); countMaterialFacets++; @@ -209,7 +211,7 @@ bool ReaderOBJ::Load(std::istream &str) _material->binding = MeshIO::PER_VERTEX; _material->diffuseColor.reserve(meshPoints.size()); - for (const auto & it : meshPoints) { + for (const auto& it : meshPoints) { unsigned long prop = it._ulProp; App::Color c; c.setPackedValue(static_cast(prop)); @@ -218,40 +220,44 @@ bool ReaderOBJ::Load(std::istream &str) } } else if (!materialName.empty()) { - // At this point the materials from the .mtl file are not known and will be read-in by the calling instance - // but the color list is pre-filled with a default value + // At this point the materials from the .mtl file are not known and will be read-in by the + // calling instance but the color list is pre-filled with a default value if (_material) { _material->binding = MeshIO::PER_FACE; _material->diffuseColor.resize(meshFacets.size(), App::Color(0.8f, 0.8f, 0.8f)); } } - _kernel.Clear(); // remove all data before + _kernel.Clear(); // remove all data before MeshCleanup meshCleanup(meshPoints, meshFacets); - if (_material) + if (_material) { meshCleanup.SetMaterial(_material); + } meshCleanup.RemoveInvalids(); - MeshPointFacetAdjacency meshAdj(meshPoints.size(),meshFacets); + MeshPointFacetAdjacency meshAdj(meshPoints.size(), meshFacets); meshAdj.SetFacetNeighbourhood(); - _kernel.Adopt(meshPoints,meshFacets); + _kernel.Adopt(meshPoints, meshFacets); return true; } -bool ReaderOBJ::LoadMaterial(std::istream &str) +bool ReaderOBJ::LoadMaterial(std::istream& str) { std::string line; - if (!_material) + if (!_material) { return false; + } - if (!str || str.bad()) + if (!str || str.bad()) { return false; + } std::streambuf* buf = str.rdbuf(); - if (!buf) + if (!buf) { return false; + } std::map materialAmbientColor; std::map materialDiffuseColor; @@ -281,9 +287,9 @@ bool ReaderOBJ::LoadMaterial(std::istream &str) while (std::getline(str, line)) { boost::char_separator sep(" "); - boost::tokenizer > tokens(line, sep); + boost::tokenizer> tokens(line, sep); std::vector token_results; - token_results.assign(tokens.begin(),tokens.end()); + token_results.assign(tokens.begin(), tokens.end()); try { if (token_results.size() >= 2) { @@ -312,7 +318,7 @@ bool ReaderOBJ::LoadMaterial(std::istream &str) } } - for (const auto & it : _materialNames) { + for (const auto& it : _materialNames) { { auto jt = materialAmbientColor.find(it.first); if (jt != materialAmbientColor.end()) { diff --git a/src/Mod/Mesh/App/Core/IO/ReaderOBJ.h b/src/Mod/Mesh/App/Core/IO/ReaderOBJ.h index 96ac75cb94..e951a959e0 100644 --- a/src/Mod/Mesh/App/Core/IO/ReaderOBJ.h +++ b/src/Mod/Mesh/App/Core/IO/ReaderOBJ.h @@ -24,9 +24,9 @@ #ifndef MESH_IO_READER_OBJ_H #define MESH_IO_READER_OBJ_H -#include #include #include +#include namespace MeshCore { @@ -46,16 +46,17 @@ public: * \brief Load the mesh from the input stream * \return true on success and false otherwise */ - bool Load(std::istream &str); + bool Load(std::istream& str); /*! * \brief Load the material file to the corresponding OBJ file. * This function must be called after \ref Load(). * \param str * \return true on success and false otherwise */ - bool LoadMaterial(std::istream &str); + bool LoadMaterial(std::istream& str); - const std::vector& GetGroupNames() const { + const std::vector& GetGroupNames() const + { return _groupNames; } @@ -63,10 +64,10 @@ private: MeshKernel& _kernel; Material* _material; std::vector _groupNames; - std::vector > _materialNames; + std::vector> _materialNames; }; -} // namespace MeshCore +} // namespace MeshCore #endif // MESH_IO_READER_OBJ_H diff --git a/src/Mod/Mesh/App/Core/IO/Writer3MF.cpp b/src/Mod/Mesh/App/Core/IO/Writer3MF.cpp index 15c29286da..05937ca3e8 100644 --- a/src/Mod/Mesh/App/Core/IO/Writer3MF.cpp +++ b/src/Mod/Mesh/App/Core/IO/Writer3MF.cpp @@ -22,28 +22,28 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include +#include +#include #endif -#include #include "Core/Evaluation.h" #include "Core/MeshKernel.h" +#include #include "Writer3MF.h" using namespace MeshCore; -Writer3MF::Writer3MF(std::ostream &str) - : zip(str) +Writer3MF::Writer3MF(std::ostream& str) + : zip(str) { zip.putNextEntry("3D/3dmodel.model"); Initialize(zip); } -Writer3MF::Writer3MF(const std::string &filename) - : zip(filename) +Writer3MF::Writer3MF(const std::string& filename) + : zip(filename) { zip.putNextEntry("3D/3dmodel.model"); Initialize(zip); @@ -54,15 +54,16 @@ void Writer3MF::SetForceModel(bool model) forceModel = model; } -void Writer3MF::Initialize(std::ostream &str) +void Writer3MF::Initialize(std::ostream& str) { str << "\n" - "\n" + "\n" " FreeCAD\n"; str << Base::blanks(1) << "\n"; } -void Writer3MF::Finish(std::ostream &str) +void Writer3MF::Finish(std::ostream& str) { str << Base::blanks(1) << "\n"; str << Base::blanks(1) << "\n"; @@ -110,7 +111,7 @@ bool Writer3MF::Save() return true; } -bool Writer3MF::SaveObject(std::ostream &str, int id, const MeshKernel& mesh) const +bool Writer3MF::SaveObject(std::ostream& str, int id, const MeshKernel& mesh) const { // NOLINTBEGIN(readability-magic-numbers, cppcoreguidelines-avoid-magic-numbers) const MeshPointArray& rPoints = mesh.GetPoints(); @@ -127,20 +128,16 @@ bool Writer3MF::SaveObject(std::ostream &str, int id, const MeshKernel& mesh) co str << Base::blanks(4) << "\n"; std::size_t index = 0; for (auto it = rPoints.begin(); it != rPoints.end(); ++it, ++index) { - str << Base::blanks(5) << "x - << "\" y=\"" << it->y - << "\" z=\"" << it->z - << "\" />\n"; + str << Base::blanks(5) << "x << "\" y=\"" << it->y << "\" z=\"" + << it->z << "\" />\n"; } str << Base::blanks(4) << "\n"; // facet indices str << Base::blanks(4) << "\n"; - for (const auto & it : rFacets) { - str << Base::blanks(5) << "\n"; + for (const auto& it : rFacets) { + str << Base::blanks(5) << "\n"; } str << Base::blanks(4) << "\n"; @@ -173,25 +170,24 @@ std::string Writer3MF::DumpMatrix(const Base::Matrix4D& mat) // 3D Manufacturing Format / Core Specification & Reference Guide v1.2.3 // Chapter: 3.3 3D Matrices (page 9) std::stringstream str; - str << mat[0][0] << " " << mat[1][0] << " " << mat[2][0] << " " - << mat[0][1] << " " << mat[1][1] << " " << mat[2][1] << " " - << mat[0][2] << " " << mat[1][2] << " " << mat[2][2] << " " + str << mat[0][0] << " " << mat[1][0] << " " << mat[2][0] << " " << mat[0][1] << " " << mat[1][1] + << " " << mat[2][1] << " " << mat[0][2] << " " << mat[1][2] << " " << mat[2][2] << " " << mat[0][3] << " " << mat[1][3] << " " << mat[2][3]; return str.str(); // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) } -bool Writer3MF::SaveRels(std::ostream &str) const +bool Writer3MF::SaveRels(std::ostream& str) const { // NOLINTBEGIN(modernize-raw-string-literal) int ids = 1; str << "\n" - << "\n" + << "\n" << " \n"; for (const auto& it : resources) { - str << " \n"; } str << "\n"; @@ -199,15 +195,17 @@ bool Writer3MF::SaveRels(std::ostream &str) const // NOLINTEND(modernize-raw-string-literal) } -bool Writer3MF::SaveContent(std::ostream &str) const +bool Writer3MF::SaveContent(std::ostream& str) const { str << "\n" << "\n" - << " \n" - << " \n"; + << " \n" + << " \n"; for (const auto& it : resources) { - str << " \n"; + str << " \n"; } str << ""; return true; diff --git a/src/Mod/Mesh/App/Core/IO/Writer3MF.h b/src/Mod/Mesh/App/Core/IO/Writer3MF.h index cb5f5df834..af0813dec8 100644 --- a/src/Mod/Mesh/App/Core/IO/Writer3MF.h +++ b/src/Mod/Mesh/App/Core/IO/Writer3MF.h @@ -24,11 +24,12 @@ #ifndef MESH_IO_WRITER_3MF_H #define MESH_IO_WRITER_3MF_H +#include #include #include -#include -namespace Base { +namespace Base +{ class Matrix4D; } @@ -36,7 +37,8 @@ namespace MeshCore { class MeshKernel; -struct Resource3MF { +struct Resource3MF +{ std::string extension; std::string contentType; std::string relationshipTarget; @@ -54,14 +56,14 @@ public: * Passes an output stream to the constructor. * \param str */ - explicit Writer3MF(std::ostream &str); + explicit Writer3MF(std::ostream& str); /*! * \brief Writer3MF * Passes a file name to the constructor * \param filename */ - explicit Writer3MF(const std::string &filename); + explicit Writer3MF(const std::string& filename); /*! * \brief SetForceModel * Forcces to write the mesh as model even if itsn't a solid. @@ -88,14 +90,14 @@ public: bool Save(); private: - static void Initialize(std::ostream &str); - void Finish(std::ostream &str); + static void Initialize(std::ostream& str); + void Finish(std::ostream& str); std::string GetType(const MeshKernel& mesh) const; void SaveBuildItem(int id, const Base::Matrix4D& mat); static std::string DumpMatrix(const Base::Matrix4D& mat); - bool SaveObject(std::ostream &str, int id, const MeshKernel& mesh) const; - bool SaveRels(std::ostream &str) const; - bool SaveContent(std::ostream &str) const; + bool SaveObject(std::ostream& str, int id, const MeshKernel& mesh) const; + bool SaveRels(std::ostream& str) const; + bool SaveContent(std::ostream& str) const; private: zipios::ZipOutputStream zip; @@ -105,7 +107,7 @@ private: bool forceModel = true; }; -} // namespace MeshCore +} // namespace MeshCore #endif // MESH_IO_WRITER_3MF_H diff --git a/src/Mod/Mesh/App/Core/IO/WriterInventor.cpp b/src/Mod/Mesh/App/Core/IO/WriterInventor.cpp index f19487ed66..aa401c2091 100644 --- a/src/Mod/Mesh/App/Core/IO/WriterInventor.cpp +++ b/src/Mod/Mesh/App/Core/IO/WriterInventor.cpp @@ -22,9 +22,9 @@ #include "PreCompiled.h" +#include "Core/Iterator.h" #include #include -#include "Core/Iterator.h" #include "WriterInventor.h" @@ -43,8 +43,7 @@ public: WriterInventorImp(Base::InventorBuilder& builder) : builder(builder) - { - } + {} void setupStream(std::ostream& out) { @@ -54,31 +53,29 @@ public: void addInfoNode() { - Base::InfoItem info{"Created by FreeCAD "}; + Base::InfoItem info {"Created by FreeCAD "}; builder.addNode(info); } void addLabel(const MeshCore::MeshKernel& kernel) { std::stringstream str; - str << "Triangle mesh contains " - << kernel.CountPoints() - << " vertices and " - << kernel.CountFacets() - << " faces"; - Base::LabelItem label{str.str().c_str()}; + str << "Triangle mesh contains " << kernel.CountPoints() << " vertices and " + << kernel.CountFacets() << " faces"; + Base::LabelItem label {str.str().c_str()}; builder.addNode(label); } void addTransformNode(const Base::Matrix4D& mat, bool append) { - if (!append) + if (!append) { return; + } Base::Placement placement; placement.fromMatrix(mat); - Base::TransformItem item{placement}; + Base::TransformItem item {placement}; builder.addNode(item); } @@ -100,7 +97,7 @@ public: ++clIter; } - builder.addNode(Base::NormalItem{normals}); + builder.addNode(Base::NormalItem {normals}); Base::NormalBindingItem binding; binding.setValue(Base::BindingElement::Binding::PerFace); @@ -116,20 +113,24 @@ public: coords.reserve(points.size()); coords.insert(coords.begin(), points.begin(), points.end()); - builder.addNode(Base::Coordinate3Item{coords}); + builder.addNode(Base::Coordinate3Item {coords}); } void addMaterialNode(const Material* material) { - if (!material) + if (!material) { return; + } auto transformColors = [](const std::vector& input) { std::vector output; output.reserve(input.size()); - std::transform(input.cbegin(), input.cend(), std::back_inserter(output), [](const App::Color& col) { - return Base::ColorRGB{col.r, col.g, col.b}; - }); + std::transform(input.cbegin(), + input.cend(), + std::back_inserter(output), + [](const App::Color& col) { + return Base::ColorRGB {col.r, col.g, col.b}; + }); return output; }; @@ -146,20 +147,21 @@ public: void addMaterialBindingNode(const Material* material) { - if (!material) + if (!material) { return; + } Base::MaterialBindingItem binding; switch (material->binding) { - case MeshIO::PER_FACE: - binding.setValue(Base::BindingElement::Binding::PerFace); - break; - case MeshIO::PER_VERTEX: - binding.setValue(Base::BindingElement::Binding::PerVertex); - break; - default: - binding.setValue(Base::BindingElement::Binding::Overall); - break; + case MeshIO::PER_FACE: + binding.setValue(Base::BindingElement::Binding::PerFace); + break; + case MeshIO::PER_VERTEX: + binding.setValue(Base::BindingElement::Binding::PerVertex); + break; + default: + binding.setValue(Base::BindingElement::Binding::Overall); + break; } builder.addNode(binding); @@ -178,32 +180,33 @@ public: indices.push_back(-1); } - builder.addNode(Base::IndexedFaceSetItem{indices}); + builder.addNode(Base::IndexedFaceSetItem {indices}); } }; WriterInventor::WriterInventor(const MeshKernel& kernel, const Material* material) - : _kernel(kernel) - , _material(material) -{ -} + : _kernel(kernel) + , _material(material) +{} void WriterInventor::SetTransform(const Base::Matrix4D& mat) { _transform = mat; - if (mat != Base::Matrix4D()) + if (mat != Base::Matrix4D()) { apply_transform = true; + } } bool WriterInventor::Save(std::ostream& out) { - if (WriterInventorImp::isStreamInvalid(out)) + if (WriterInventorImp::isStreamInvalid(out)) { return false; + } Base::InventorBuilder builder(out); builder.beginSeparator(); - WriterInventorImp writer{builder}; + WriterInventorImp writer {builder}; writer.setupStream(out); writer.addInfoNode(); writer.addLabel(_kernel); diff --git a/src/Mod/Mesh/App/Core/IO/WriterInventor.h b/src/Mod/Mesh/App/Core/IO/WriterInventor.h index 5d25c188e1..fa56725166 100644 --- a/src/Mod/Mesh/App/Core/IO/WriterInventor.h +++ b/src/Mod/Mesh/App/Core/IO/WriterInventor.h @@ -24,8 +24,8 @@ #ifndef MESH_IO_WRITER_IV_H #define MESH_IO_WRITER_IV_H -#include #include +#include namespace MeshCore { @@ -52,10 +52,10 @@ private: const MeshKernel& _kernel; const Material* _material; Base::Matrix4D _transform; - bool apply_transform{false}; + bool apply_transform {false}; }; -} // namespace MeshCore +} // namespace MeshCore #endif // MESH_IO_WRITER_IV_H diff --git a/src/Mod/Mesh/App/Core/IO/WriterOBJ.cpp b/src/Mod/Mesh/App/Core/IO/WriterOBJ.cpp index 534bed80a7..6ae501772b 100644 --- a/src/Mod/Mesh/App/Core/IO/WriterOBJ.cpp +++ b/src/Mod/Mesh/App/Core/IO/WriterOBJ.cpp @@ -22,10 +22,10 @@ #include "PreCompiled.h" +#include "Core/Iterator.h" #include #include #include -#include "Core/Iterator.h" #include "WriterOBJ.h" @@ -34,24 +34,25 @@ using namespace MeshCore; struct WriterOBJ::Color_Less { - bool operator()(const App::Color& x, - const App::Color& y) const + bool operator()(const App::Color& x, const App::Color& y) const { - if (x.r != y.r) + if (x.r != y.r) { return x.r < y.r; - if (x.g != y.g) + } + if (x.g != y.g) { return x.g < y.g; - if (x.b != y.b) + } + if (x.b != y.b) { return x.b < y.b; - return false; // equal colors + } + return false; // equal colors } }; WriterOBJ::WriterOBJ(const MeshKernel& kernel, const Material* material) - : _kernel(kernel) - , _material(material) -{ -} + : _kernel(kernel) + , _material(material) +{} void WriterOBJ::SetGroups(const std::vector& g) { @@ -61,8 +62,9 @@ void WriterOBJ::SetGroups(const std::vector& g) void WriterOBJ::SetTransform(const Base::Matrix4D& mat) { _transform = mat; - if (mat != Base::Matrix4D()) + if (mat != Base::Matrix4D()) { apply_transform = true; + } } bool WriterOBJ::Save(std::ostream& out) @@ -70,8 +72,9 @@ bool WriterOBJ::Save(std::ostream& out) const MeshPointArray& rPoints = _kernel.GetPoints(); const MeshFacetArray& rFacets = _kernel.GetFacets(); - if (!out || out.bad()) + if (!out || out.bad()) { return false; + } Base::SequencerLauncher seq("saving...", _kernel.CountPoints() + _kernel.CountFacets()); bool exportColorPerVertex = false; @@ -80,7 +83,8 @@ bool WriterOBJ::Save(std::ostream& out) if (_material) { if (_material->binding == MeshIO::PER_FACE) { if (_material->diffuseColor.size() != rFacets.size()) { - Base::Console().Warning("Cannot export color information because there is a different number of faces and colors"); + Base::Console().Warning("Cannot export color information because there is a " + "different number of faces and colors"); } else { exportColorPerFace = true; @@ -88,7 +92,8 @@ bool WriterOBJ::Save(std::ostream& out) } else if (_material->binding == MeshIO::PER_VERTEX) { if (_material->diffuseColor.size() != rPoints.size()) { - Base::Console().Warning("Cannot export color information because there is a different number of points and colors"); + Base::Console().Warning("Cannot export color information because there is a " + "different number of points and colors"); } else { exportColorPerVertex = true; @@ -96,7 +101,8 @@ bool WriterOBJ::Save(std::ostream& out) } else if (_material->binding == MeshIO::OVERALL) { if (_material->diffuseColor.empty()) { - Base::Console().Warning("Cannot export color information because there is no color defined"); + Base::Console().Warning( + "Cannot export color information because there is no color defined"); } else { exportColorPerVertex = true; @@ -137,12 +143,13 @@ bool WriterOBJ::Save(std::ostream& out) int g = static_cast(c.g * 255.0f); int b = static_cast(c.b * 255.0f); - out << "v " << pt.x << " " << pt.y << " " << pt.z << " " << r << " " << g << " " << b << '\n'; + out << "v " << pt.x << " " << pt.y << " " << pt.z << " " << r << " " << g << " " << b + << '\n'; } else { out << "v " << pt.x << " " << pt.y << " " << pt.z << '\n'; } - seq.next(true); // allow to cancel + seq.next(true); // allow to cancel } // Export normals MeshFacetIterator clIter(_kernel), clEnd(_kernel); @@ -153,11 +160,10 @@ bool WriterOBJ::Save(std::ostream& out) while (clIter < clEnd) { pclFacet = &(*clIter); - out << "vn " << pclFacet->GetNormal().x << " " - << pclFacet->GetNormal().y << " " + out << "vn " << pclFacet->GetNormal().x << " " << pclFacet->GetNormal().y << " " << pclFacet->GetNormal().z << '\n'; ++clIter; - seq.next(true); // allow to cancel + seq.next(true); // allow to cancel } if (_groups.empty()) { @@ -173,29 +179,31 @@ bool WriterOBJ::Save(std::ostream& out) App::Color prev; int faceIdx = 1; const std::vector& Kd = _material->diffuseColor; - for (MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); ++it, index++) { + for (MeshFacetArray::_TConstIterator it = rFacets.begin(); it != rFacets.end(); + ++it, index++) { if (index == 0 || prev != Kd[index]) { prev = Kd[index]; - std::vector::iterator c_it = std::find(colors.begin(), colors.end(), prev); + std::vector::iterator c_it = + std::find(colors.begin(), colors.end(), prev); if (c_it != colors.end()) { out << "usemtl material_" << (c_it - colors.begin()) << '\n'; } } - out << "f " << it->_aulPoints[0]+1 << "//" << faceIdx << " " - << it->_aulPoints[1]+1 << "//" << faceIdx << " " - << it->_aulPoints[2]+1 << "//" << faceIdx << '\n'; - seq.next(true); // allow to cancel + out << "f " << it->_aulPoints[0] + 1 << "//" << faceIdx << " " + << it->_aulPoints[1] + 1 << "//" << faceIdx << " " << it->_aulPoints[2] + 1 + << "//" << faceIdx << '\n'; + seq.next(true); // allow to cancel faceIdx++; } } else { // facet indices (no texture and normal indices) std::size_t faceIdx = 1; - for (const auto & it : rFacets) { - out << "f " << it._aulPoints[0]+1 << "//" << faceIdx << " " - << it._aulPoints[1]+1 << "//" << faceIdx << " " - << it._aulPoints[2]+1 << "//" << faceIdx << '\n'; - seq.next(true); // allow to cancel + for (const auto& it : rFacets) { + out << "f " << it._aulPoints[0] + 1 << "//" << faceIdx << " " + << it._aulPoints[1] + 1 << "//" << faceIdx << " " << it._aulPoints[2] + 1 + << "//" << faceIdx << '\n'; + seq.next(true); // allow to cancel faceIdx++; } } @@ -211,35 +219,36 @@ bool WriterOBJ::Save(std::ostream& out) App::Color prev; const std::vector& Kd = _material->diffuseColor; - for (const auto & gt : _groups) { + for (const auto& gt : _groups) { out << "g " << Base::Tools::escapedUnicodeFromUtf8(gt.name.c_str()) << '\n'; for (FacetIndex it : gt.indices) { const MeshFacet& f = rFacets[it]; if (first || prev != Kd[it]) { first = false; prev = Kd[it]; - std::vector::iterator c_it = std::find(colors.begin(), colors.end(), prev); + std::vector::iterator c_it = + std::find(colors.begin(), colors.end(), prev); if (c_it != colors.end()) { out << "usemtl material_" << (c_it - colors.begin()) << '\n'; } } - out << "f " << f._aulPoints[0]+1 << "//" << it + 1 << " " - << f._aulPoints[1]+1 << "//" << it + 1 << " " - << f._aulPoints[2]+1 << "//" << it + 1 << '\n'; - seq.next(true); // allow to cancel + out << "f " << f._aulPoints[0] + 1 << "//" << it + 1 << " " + << f._aulPoints[1] + 1 << "//" << it + 1 << " " << f._aulPoints[2] + 1 + << "//" << it + 1 << '\n'; + seq.next(true); // allow to cancel } } } else { - for (const auto & gt : _groups) { + for (const auto& gt : _groups) { out << "g " << Base::Tools::escapedUnicodeFromUtf8(gt.name.c_str()) << '\n'; for (FacetIndex it : gt.indices) { const MeshFacet& f = rFacets[it]; - out << "f " << f._aulPoints[0]+1 << "//" << it + 1 << " " - << f._aulPoints[1]+1 << "//" << it + 1 << " " - << f._aulPoints[2]+1 << "//" << it + 1 << '\n'; - seq.next(true); // allow to cancel + out << "f " << f._aulPoints[0] + 1 << "//" << it + 1 << " " + << f._aulPoints[1] + 1 << "//" << it + 1 << " " << f._aulPoints[2] + 1 + << "//" << it + 1 << '\n'; + seq.next(true); // allow to cancel } } } @@ -250,8 +259,9 @@ bool WriterOBJ::Save(std::ostream& out) bool WriterOBJ::SaveMaterial(std::ostream& out) { - if (!out || out.bad()) + if (!out || out.bad()) { return false; + } if (_material) { if (_material->binding == MeshIO::PER_FACE) { @@ -265,7 +275,7 @@ bool WriterOBJ::SaveMaterial(std::ostream& out) out << "# Created by FreeCAD : 'None'\n"; out << "# Material Count: " << Kd.size() << '\n'; - for (std::size_t i=0; i #include +#include namespace MeshCore { @@ -66,11 +66,11 @@ private: const MeshKernel& _kernel; const Material* _material; Base::Matrix4D _transform; - bool apply_transform{false}; + bool apply_transform {false}; std::vector _groups; }; -} // namespace MeshCore +} // namespace MeshCore #endif // MESH_IO_WRITER_OBJ_H diff --git a/src/Mod/Mesh/App/Core/Info.cpp b/src/Mod/Mesh/App/Core/Info.cpp index a7f80fe47b..2269f567b5 100644 --- a/src/Mod/Mesh/App/Core/Info.cpp +++ b/src/Mod/Mesh/App/Core/Info.cpp @@ -23,10 +23,10 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include -# include +#include +#include +#include +#include #endif #include "Info.h" @@ -35,218 +35,205 @@ using namespace MeshCore; -MeshInfo::MeshInfo (const MeshKernel &rclM) -: _rclMesh(rclM) +MeshInfo::MeshInfo(const MeshKernel& rclM) + : _rclMesh(rclM) +{} + +std::ostream& MeshInfo::GeneralInformation(std::ostream& rclStream) const { + unsigned long ulCtPt, ulCtEd, ulCtFc; + ulCtPt = _rclMesh.CountPoints(); + ulCtFc = _rclMesh.CountFacets(); + ulCtEd = _rclMesh.CountEdges(); + + rclStream << "Mesh: [" << ulCtFc << " Faces, "; + rclStream << ulCtEd << " Edges, "; + rclStream << ulCtPt << " Points" + << "]" << std::endl; + + return rclStream; } -std::ostream& MeshInfo::GeneralInformation (std::ostream &rclStream) const +std::ostream& MeshInfo::DetailedPointInfo(std::ostream& rclStream) const { - unsigned long ulCtPt, ulCtEd, ulCtFc; - ulCtPt = _rclMesh.CountPoints(); - ulCtFc = _rclMesh.CountFacets(); - ulCtEd = _rclMesh.CountEdges(); + // print points + rclStream << _rclMesh.CountPoints() << " Points:" << std::endl; + MeshPointIterator pPIter(_rclMesh), pPEnd(_rclMesh); + pPIter.Begin(); + pPEnd.End(); + PointIndex i = 0; - rclStream << "Mesh: [" - << ulCtFc << " Faces, "; - rclStream << ulCtEd << " Edges, "; - rclStream << ulCtPt << " Points" - << "]" << std::endl; - - return rclStream; -} - -std::ostream& MeshInfo::DetailedPointInfo (std::ostream& rclStream) const -{ - // print points - rclStream << _rclMesh.CountPoints() << " Points:" << std::endl; - MeshPointIterator pPIter(_rclMesh), pPEnd(_rclMesh); - pPIter.Begin(); - pPEnd.End(); - PointIndex i = 0; - - rclStream.precision(3); - rclStream.setf(std::ios::fixed | std::ios::showpoint | std::ios::showpos); - while (pPIter < pPEnd) - { - rclStream << "P " << std::setw(4) << (i++) << ": (" - << std::setw(8) << (*pPIter).x << ", " - << std::setw(8) << (*pPIter).y << ", " - << std::setw(8) << (*pPIter).z << ")" << std::endl; - ++pPIter; - } - - return rclStream; -} - -std::ostream& MeshInfo::DetailedEdgeInfo (std::ostream& rclStream) const -{ - // print edges - // get edges from facets - std::map, int > lEdges; - - const MeshFacetArray& rFacets = _rclMesh.GetFacets(); - MeshFacetArray::_TConstIterator pFIter; - pFIter = rFacets.begin(); - while (pFIter < rFacets.end()) - { - const MeshFacet& rFacet = *pFIter; - for ( int j=0; j<3; j++ ) - { - PointIndex ulPt0 = std::min(rFacet._aulPoints[j], rFacet._aulPoints[(j+1)%3]); - PointIndex ulPt1 = std::max(rFacet._aulPoints[j], rFacet._aulPoints[(j+1)%3]); - std::pair cEdge(ulPt0, ulPt1); - lEdges[ cEdge ]++; + rclStream.precision(3); + rclStream.setf(std::ios::fixed | std::ios::showpoint | std::ios::showpos); + while (pPIter < pPEnd) { + rclStream << "P " << std::setw(4) << (i++) << ": (" << std::setw(8) << (*pPIter).x << ", " + << std::setw(8) << (*pPIter).y << ", " << std::setw(8) << (*pPIter).z << ")" + << std::endl; + ++pPIter; } - pFIter++; - } - - // print edges - rclStream << lEdges.size() << " Edges:" << std::endl; - std::map, int >::const_iterator pEIter; - pEIter = lEdges.begin(); - - rclStream.precision(3); - rclStream.setf(std::ios::fixed | std::ios::showpoint | std::ios::showpos); - unsigned long i=0; - const MeshPointArray& rPoints = _rclMesh.GetPoints(); - while (pEIter != lEdges.end()) - { - int ct = pEIter->second; - const Base::Vector3f& rP0 = rPoints[ pEIter->first.first ]; - const Base::Vector3f& rP1 = rPoints[ pEIter->first.second ]; - - rclStream << "E " << std::setw(4) << (i++) << ": " - << " P (" << std::setw(8) << rP0.x << ", " - << std::setw(8) << rP0.y << ", " - << std::setw(8) << rP0.z << "); " - << " P (" << std::setw(8) << rP1.x << ", " - << std::setw(8) << rP1.y << ", " - << std::setw(8) << rP1.z << "), B: " << (ct == 2 ? "n" : "y") << std::endl; - ++pEIter; - } - - return rclStream; + return rclStream; } -std::ostream& MeshInfo::DetailedFacetInfo (std::ostream& rclStream) const +std::ostream& MeshInfo::DetailedEdgeInfo(std::ostream& rclStream) const { - // print facets - unsigned long i, j; - rclStream << _rclMesh.CountFacets() << " Faces:" << std::endl; - MeshFacetIterator pFIter(_rclMesh), pFEnd(_rclMesh); - pFIter.Begin(); - pFEnd.End(); - i = 0; + // print edges + // get edges from facets + std::map, int> lEdges; - rclStream.precision(3); - rclStream.setf(std::ios::fixed | std::ios::showpoint | std::ios::showpos); - while (pFIter < pFEnd) - { - rclStream << "F " << std::setw(4) << (i++) << ":" << std::endl; - rclStream << " N (" << std::setw(8) << (*pFIter).GetNormal().x << ", " - << std::setw(8) << (*pFIter).GetNormal().y << ", " - << std::setw(8) << (*pFIter).GetNormal().z << ")" << std::endl; - for (j = 0; j < 3; j++) - { - rclStream << " P (" << std::setw(8) << (*pFIter)._aclPoints[j].x << ", " - << std::setw(8) << (*pFIter)._aclPoints[j].y << ", " - << std::setw(8) << (*pFIter)._aclPoints[j].z << ")" << std::endl; + const MeshFacetArray& rFacets = _rclMesh.GetFacets(); + MeshFacetArray::_TConstIterator pFIter; + pFIter = rFacets.begin(); + while (pFIter < rFacets.end()) { + const MeshFacet& rFacet = *pFIter; + for (int j = 0; j < 3; j++) { + PointIndex ulPt0 = + std::min(rFacet._aulPoints[j], rFacet._aulPoints[(j + 1) % 3]); + PointIndex ulPt1 = + std::max(rFacet._aulPoints[j], rFacet._aulPoints[(j + 1) % 3]); + std::pair cEdge(ulPt0, ulPt1); + lEdges[cEdge]++; + } + + pFIter++; } - ++pFIter; - } - return rclStream; + // print edges + rclStream << lEdges.size() << " Edges:" << std::endl; + std::map, int>::const_iterator pEIter; + pEIter = lEdges.begin(); + + rclStream.precision(3); + rclStream.setf(std::ios::fixed | std::ios::showpoint | std::ios::showpos); + unsigned long i = 0; + const MeshPointArray& rPoints = _rclMesh.GetPoints(); + while (pEIter != lEdges.end()) { + int ct = pEIter->second; + const Base::Vector3f& rP0 = rPoints[pEIter->first.first]; + const Base::Vector3f& rP1 = rPoints[pEIter->first.second]; + + rclStream << "E " << std::setw(4) << (i++) << ": " + << " P (" << std::setw(8) << rP0.x << ", " << std::setw(8) << rP0.y << ", " + << std::setw(8) << rP0.z << "); " + << " P (" << std::setw(8) << rP1.x << ", " << std::setw(8) << rP1.y << ", " + << std::setw(8) << rP1.z << "), B: " << (ct == 2 ? "n" : "y") << std::endl; + ++pEIter; + } + + return rclStream; } -std::ostream& MeshInfo::DetailedInformation (std::ostream& rclStream) const +std::ostream& MeshInfo::DetailedFacetInfo(std::ostream& rclStream) const { - DetailedPointInfo( rclStream ); - DetailedEdgeInfo ( rclStream ); - DetailedFacetInfo( rclStream ); + // print facets + unsigned long i, j; + rclStream << _rclMesh.CountFacets() << " Faces:" << std::endl; + MeshFacetIterator pFIter(_rclMesh), pFEnd(_rclMesh); + pFIter.Begin(); + pFEnd.End(); + i = 0; - return rclStream; + rclStream.precision(3); + rclStream.setf(std::ios::fixed | std::ios::showpoint | std::ios::showpos); + while (pFIter < pFEnd) { + rclStream << "F " << std::setw(4) << (i++) << ":" << std::endl; + rclStream << " N (" << std::setw(8) << (*pFIter).GetNormal().x << ", " << std::setw(8) + << (*pFIter).GetNormal().y << ", " << std::setw(8) << (*pFIter).GetNormal().z + << ")" << std::endl; + for (j = 0; j < 3; j++) { + rclStream << " P (" << std::setw(8) << (*pFIter)._aclPoints[j].x << ", " + << std::setw(8) << (*pFIter)._aclPoints[j].y << ", " << std::setw(8) + << (*pFIter)._aclPoints[j].z << ")" << std::endl; + } + ++pFIter; + } + + return rclStream; } -std::ostream& MeshInfo::InternalPointInfo (std::ostream& rclStream) const +std::ostream& MeshInfo::DetailedInformation(std::ostream& rclStream) const { - // print points - unsigned long i; - rclStream << _rclMesh.CountPoints() << " Points:" << std::endl; - MeshPointIterator pPIter(_rclMesh), pPEnd(_rclMesh); - pPIter.Begin(); - pPEnd.End(); - i = 0; + DetailedPointInfo(rclStream); + DetailedEdgeInfo(rclStream); + DetailedFacetInfo(rclStream); - rclStream.precision(3); - rclStream.setf(std::ios::fixed | std::ios::showpoint | std::ios::showpos); - while (pPIter < pPEnd) - { - rclStream << "P " << std::setw(4) << (i++) << ": (" - << std::setw(8) << (*pPIter).x << ", " - << std::setw(8) << (*pPIter).y << ", " - << std::setw(8) << (*pPIter).z << ")"; - if (pPIter->IsValid()) - rclStream << std::endl; - else - rclStream << " invalid" << std::endl; - ++pPIter; - } - - return rclStream; + return rclStream; } -std::ostream& MeshInfo::InternalFacetInfo (std::ostream& rclStream) const +std::ostream& MeshInfo::InternalPointInfo(std::ostream& rclStream) const { - // print facets - unsigned long i; - rclStream << _rclMesh.CountFacets() << " Faces:" << std::endl; + // print points + unsigned long i; + rclStream << _rclMesh.CountPoints() << " Points:" << std::endl; + MeshPointIterator pPIter(_rclMesh), pPEnd(_rclMesh); + pPIter.Begin(); + pPEnd.End(); + i = 0; - const MeshFacetArray& rFacets = _rclMesh.GetFacets(); - MeshFacetArray::_TConstIterator pFIter; - pFIter = rFacets.begin(); - i = 0; - while (pFIter < rFacets.end()) - { - rclStream << "F " << std::setw(4) << (i++) << ": P (" - << std::setw(4) << pFIter->_aulPoints[0] << ", " - << std::setw(4) << pFIter->_aulPoints[1] << ", " - << std::setw(4) << pFIter->_aulPoints[2] << ") " - << "N (" << std::setw(4) << pFIter->_aulNeighbours[0] << ", " - << std::setw(4) << pFIter->_aulNeighbours[1] << ", " - << std::setw(4) << pFIter->_aulNeighbours[2] << ") "; + rclStream.precision(3); + rclStream.setf(std::ios::fixed | std::ios::showpoint | std::ios::showpos); + while (pPIter < pPEnd) { + rclStream << "P " << std::setw(4) << (i++) << ": (" << std::setw(8) << (*pPIter).x << ", " + << std::setw(8) << (*pPIter).y << ", " << std::setw(8) << (*pPIter).z << ")"; + if (pPIter->IsValid()) { + rclStream << std::endl; + } + else { + rclStream << " invalid" << std::endl; + } + ++pPIter; + } - if (pFIter->IsValid()) - rclStream << std::endl; - else - rclStream << " invalid" << std::endl; - - pFIter++; - } - - return rclStream; + return rclStream; } -std::ostream& MeshInfo::InternalInformation (std::ostream& rclStream) const +std::ostream& MeshInfo::InternalFacetInfo(std::ostream& rclStream) const { - InternalPointInfo( rclStream ); - InternalFacetInfo( rclStream ); + // print facets + unsigned long i; + rclStream << _rclMesh.CountFacets() << " Faces:" << std::endl; - return rclStream; + const MeshFacetArray& rFacets = _rclMesh.GetFacets(); + MeshFacetArray::_TConstIterator pFIter; + pFIter = rFacets.begin(); + i = 0; + while (pFIter < rFacets.end()) { + rclStream << "F " << std::setw(4) << (i++) << ": P (" << std::setw(4) + << pFIter->_aulPoints[0] << ", " << std::setw(4) << pFIter->_aulPoints[1] << ", " + << std::setw(4) << pFIter->_aulPoints[2] << ") " + << "N (" << std::setw(4) << pFIter->_aulNeighbours[0] << ", " << std::setw(4) + << pFIter->_aulNeighbours[1] << ", " << std::setw(4) << pFIter->_aulNeighbours[2] + << ") "; + + if (pFIter->IsValid()) { + rclStream << std::endl; + } + else { + rclStream << " invalid" << std::endl; + } + + pFIter++; + } + + return rclStream; } -std::ostream& MeshInfo::TopologyInformation (std::ostream& rclStream) const +std::ostream& MeshInfo::InternalInformation(std::ostream& rclStream) const +{ + InternalPointInfo(rclStream); + InternalFacetInfo(rclStream); + + return rclStream; +} + +std::ostream& MeshInfo::TopologyInformation(std::ostream& rclStream) const { unsigned long index = 0; const MeshFacetArray& rFAry = _rclMesh.GetFacets(); for (MeshFacetArray::_TConstIterator it = rFAry.begin(); it != rFAry.end(); ++it, ++index) { - rclStream << "F " << std::setw(4) << index << ": P (" - << it->_aulPoints[0] << ", " - << it->_aulPoints[1] << ", " - << it->_aulPoints[2] << "), N (" - << it->_aulNeighbours[0] << ", " - << it->_aulNeighbours[1] << ", " + rclStream << "F " << std::setw(4) << index << ": P (" << it->_aulPoints[0] << ", " + << it->_aulPoints[1] << ", " << it->_aulPoints[2] << "), N (" + << it->_aulNeighbours[0] << ", " << it->_aulNeighbours[1] << ", " << it->_aulNeighbours[2] << ")" << std::endl; } diff --git a/src/Mod/Mesh/App/Core/Info.h b/src/Mod/Mesh/App/Core/Info.h index eb224e9916..930c89a54e 100644 --- a/src/Mod/Mesh/App/Core/Info.h +++ b/src/Mod/Mesh/App/Core/Info.h @@ -26,7 +26,8 @@ #include "MeshKernel.h" -namespace MeshCore { +namespace MeshCore +{ class MeshKernel; @@ -36,56 +37,56 @@ class MeshKernel; class MeshExport MeshInfo { public: - explicit MeshInfo (const MeshKernel &rclM); - virtual ~MeshInfo () = default; - /** - * Writes general information about the mesh structure into the stream. - */ - std::ostream& GeneralInformation (std::ostream& rclStream) const; - /** - * Writes detailed information about the mesh structure into the stream. - */ - std::ostream& DetailedInformation (std::ostream& rclStream) const; - /** - * Writes internal information about the mesh structure into the stream. - */ - std::ostream& InternalInformation (std::ostream& rclStream) const; - /** - * Writes topological information about the mesh structure into the stream. - */ - std::ostream& TopologyInformation (std::ostream& rclStream) const; + explicit MeshInfo(const MeshKernel& rclM); + virtual ~MeshInfo() = default; + /** + * Writes general information about the mesh structure into the stream. + */ + std::ostream& GeneralInformation(std::ostream& rclStream) const; + /** + * Writes detailed information about the mesh structure into the stream. + */ + std::ostream& DetailedInformation(std::ostream& rclStream) const; + /** + * Writes internal information about the mesh structure into the stream. + */ + std::ostream& InternalInformation(std::ostream& rclStream) const; + /** + * Writes topological information about the mesh structure into the stream. + */ + std::ostream& TopologyInformation(std::ostream& rclStream) const; protected: - /** - * Writes detailed point information. - */ - std::ostream& DetailedPointInfo (std::ostream& rclStream) const; - /** - * Writes detailed edge information. - */ - std::ostream& DetailedEdgeInfo (std::ostream& rclStream) const; - /** - * Writes detailed facet information. - */ - std::ostream& DetailedFacetInfo (std::ostream& rclStream) const; - /** - * Writes internal point information. - */ - std::ostream& InternalPointInfo (std::ostream& rclStream) const; - /** - * Writes internal facet information. - */ - std::ostream& InternalFacetInfo (std::ostream& rclStream) const; + /** + * Writes detailed point information. + */ + std::ostream& DetailedPointInfo(std::ostream& rclStream) const; + /** + * Writes detailed edge information. + */ + std::ostream& DetailedEdgeInfo(std::ostream& rclStream) const; + /** + * Writes detailed facet information. + */ + std::ostream& DetailedFacetInfo(std::ostream& rclStream) const; + /** + * Writes internal point information. + */ + std::ostream& InternalPointInfo(std::ostream& rclStream) const; + /** + * Writes internal facet information. + */ + std::ostream& InternalFacetInfo(std::ostream& rclStream) const; protected: - const MeshKernel &_rclMesh; // const reference to mesh data structure + const MeshKernel& _rclMesh; // const reference to mesh data structure public: - MeshInfo() = delete; // not accessible default constructor + MeshInfo() = delete; // not accessible default constructor }; -} // namespace MeshCore +} // namespace MeshCore #endif diff --git a/src/Mod/Mesh/App/Core/Iterator.h b/src/Mod/Mesh/App/Core/Iterator.h index bba1755bd9..ec10a72bdd 100644 --- a/src/Mod/Mesh/App/Core/Iterator.h +++ b/src/Mod/Mesh/App/Core/Iterator.h @@ -30,7 +30,8 @@ #include "MeshKernel.h" -namespace MeshCore { +namespace MeshCore +{ class MeshKernel; class MeshGeomFacet; @@ -48,433 +49,539 @@ class MeshHelpEdge; class MeshFacetIterator { public: - /** @name Construction */ - //@{ - /// construction - inline explicit MeshFacetIterator (const MeshKernel &rclM); - /// construction - inline MeshFacetIterator (const MeshKernel &rclM, FacetIndex ulPos); - /// construction - inline MeshFacetIterator (const MeshFacetIterator &rclI); - //@} + /** @name Construction */ + //@{ + /// construction + inline explicit MeshFacetIterator(const MeshKernel& rclM); + /// construction + inline MeshFacetIterator(const MeshKernel& rclM, FacetIndex ulPos); + /// construction + inline MeshFacetIterator(const MeshFacetIterator& rclI); + //@} - /** @name Transformation */ - //@{ - /// Transforms the returned facet points with the current transformation - inline void Transform( const Base::Matrix4D& rclTrf ); - //@} + /** @name Transformation */ + //@{ + /// Transforms the returned facet points with the current transformation + inline void Transform(const Base::Matrix4D& rclTrf); + //@} - /** @name Access methods */ - //@{ - /// Access to the element the iterator points to. - const MeshGeomFacet& operator*() - { return Dereference(); } - /// Access to the element the iterator points to. - const MeshGeomFacet* operator->() - { return &Dereference(); } - /// Increments the iterator. It points then to the next element if the - /// end is not reached. - const MeshFacetIterator& operator ++ () - { ++_clIter; return *this; } - /// Decrements the iterator. It points then to the previous element if the beginning - /// is not reached. - const MeshFacetIterator& operator -- () - { --_clIter; return *this; } - /// Increments the iterator by \a k positions. - const MeshFacetIterator& operator += (int k) - { _clIter += k; return *this; } - /// Decrements the iterator by \a k positions. - const MeshFacetIterator& operator -= (int k) - { _clIter -= k; return *this; } - /// Assignment. - inline MeshFacetIterator& operator = (const MeshFacetIterator &rpI); - /// Compares if this iterator points to a lower element than the other one. - bool operator < (const MeshFacetIterator &rclI) const - { return _clIter < rclI._clIter; } - /// Compares if this iterator points to a higher element than the other one. - bool operator > (const MeshFacetIterator &rclI) const - { return _clIter > rclI._clIter; } - /// Checks if the iterators points to the same element. - bool operator == (const MeshFacetIterator &rclI) const - { return _clIter == rclI._clIter; } - /// Sets the iterator to the beginning of the array. - void Begin () - { _clIter = _rclFAry.begin(); } - /// Sets the iterator to the end of the array. - void End () - { _clIter = _rclFAry.end(); } - /// Returns the current position of the iterator in the array. - FacetIndex Position () const - { return _clIter - _rclFAry.begin(); } - /// Checks if the end is already reached. - bool EndReached () const - { return !(_clIter < _rclFAry.end()); } - /// Sets the iterator to the beginning of the array. - void Init () - { Begin(); } - /// Checks if the end is not yet reached. - bool More () const - { return !EndReached(); } - /// Increments the iterator. - void Next () - { operator++(); } - /// Sets the iterator to a given position. - inline bool Set (FacetIndex ulIndex); - /// Returns the topologic facet. - inline MeshFacet GetIndices () const - { return *_clIter; } - /// Returns the topologic facet. - inline const MeshFacet& GetReference () const - { return *_clIter; } - /// Returns iterators pointing to the current facet's neighbours. - inline void GetNeighbours (MeshFacetIterator &rclN0, MeshFacetIterator &rclN1, MeshFacetIterator &rclN2) const; - /// Sets the iterator to the current facet's neighbour of the side \a usN. - inline void SetToNeighbour (unsigned short usN); - /// Returns the property information to the current facet. - inline unsigned long GetProperty () const; - /// Checks if the iterator points to a valid element inside the array. - inline bool IsValid () const - { return (_clIter >= _rclFAry.begin()) && (_clIter < _rclFAry.end()); } - //@} - /** @name Flag state - */ - //@{ - void SetFlag (MeshFacet::TFlagType tF) const - { this->_clIter->SetFlag(tF); } - void ResetFlag (MeshFacet::TFlagType tF) const - { this->_clIter->ResetFlag(tF); } - bool IsFlag (MeshFacet::TFlagType tF) const - { return this->_clIter->IsFlag(tF); } - void SetProperty(unsigned long uP) const - { this->_clIter->SetProperty(uP); } - //@} + /** @name Access methods */ + //@{ + /// Access to the element the iterator points to. + const MeshGeomFacet& operator*() + { + return Dereference(); + } + /// Access to the element the iterator points to. + const MeshGeomFacet* operator->() + { + return &Dereference(); + } + /// Increments the iterator. It points then to the next element if the + /// end is not reached. + const MeshFacetIterator& operator++() + { + ++_clIter; + return *this; + } + /// Decrements the iterator. It points then to the previous element if the beginning + /// is not reached. + const MeshFacetIterator& operator--() + { + --_clIter; + return *this; + } + /// Increments the iterator by \a k positions. + const MeshFacetIterator& operator+=(int k) + { + _clIter += k; + return *this; + } + /// Decrements the iterator by \a k positions. + const MeshFacetIterator& operator-=(int k) + { + _clIter -= k; + return *this; + } + /// Assignment. + inline MeshFacetIterator& operator=(const MeshFacetIterator& rpI); + /// Compares if this iterator points to a lower element than the other one. + bool operator<(const MeshFacetIterator& rclI) const + { + return _clIter < rclI._clIter; + } + /// Compares if this iterator points to a higher element than the other one. + bool operator>(const MeshFacetIterator& rclI) const + { + return _clIter > rclI._clIter; + } + /// Checks if the iterators points to the same element. + bool operator==(const MeshFacetIterator& rclI) const + { + return _clIter == rclI._clIter; + } + /// Sets the iterator to the beginning of the array. + void Begin() + { + _clIter = _rclFAry.begin(); + } + /// Sets the iterator to the end of the array. + void End() + { + _clIter = _rclFAry.end(); + } + /// Returns the current position of the iterator in the array. + FacetIndex Position() const + { + return _clIter - _rclFAry.begin(); + } + /// Checks if the end is already reached. + bool EndReached() const + { + return !(_clIter < _rclFAry.end()); + } + /// Sets the iterator to the beginning of the array. + void Init() + { + Begin(); + } + /// Checks if the end is not yet reached. + bool More() const + { + return !EndReached(); + } + /// Increments the iterator. + void Next() + { + operator++(); + } + /// Sets the iterator to a given position. + inline bool Set(FacetIndex ulIndex); + /// Returns the topologic facet. + inline MeshFacet GetIndices() const + { + return *_clIter; + } + /// Returns the topologic facet. + inline const MeshFacet& GetReference() const + { + return *_clIter; + } + /// Returns iterators pointing to the current facet's neighbours. + inline void GetNeighbours(MeshFacetIterator& rclN0, + MeshFacetIterator& rclN1, + MeshFacetIterator& rclN2) const; + /// Sets the iterator to the current facet's neighbour of the side \a usN. + inline void SetToNeighbour(unsigned short usN); + /// Returns the property information to the current facet. + inline unsigned long GetProperty() const; + /// Checks if the iterator points to a valid element inside the array. + inline bool IsValid() const + { + return (_clIter >= _rclFAry.begin()) && (_clIter < _rclFAry.end()); + } + //@} + /** @name Flag state + */ + //@{ + void SetFlag(MeshFacet::TFlagType tF) const + { + this->_clIter->SetFlag(tF); + } + void ResetFlag(MeshFacet::TFlagType tF) const + { + this->_clIter->ResetFlag(tF); + } + bool IsFlag(MeshFacet::TFlagType tF) const + { + return this->_clIter->IsFlag(tF); + } + void SetProperty(unsigned long uP) const + { + this->_clIter->SetProperty(uP); + } + //@} protected: - inline const MeshGeomFacet& Dereference (); + inline const MeshGeomFacet& Dereference(); protected: - const MeshKernel& _rclMesh; - const MeshFacetArray& _rclFAry; - const MeshPointArray& _rclPAry; - MeshFacetArray::_TConstIterator _clIter; - MeshGeomFacet _clFacet; - bool _bApply; - Base::Matrix4D _clTrf; + const MeshKernel& _rclMesh; + const MeshFacetArray& _rclFAry; + const MeshPointArray& _rclPAry; + MeshFacetArray::_TConstIterator _clIter; + MeshGeomFacet _clFacet; + bool _bApply; + Base::Matrix4D _clTrf; - // friends - friend class MeshKernel; + // friends + friend class MeshKernel; }; /** - * The MeshPointIterator allows to iterate over the vertices of the mesh and provides access to their - * geometric information. - * \note This class is not thread-safe. + * The MeshPointIterator allows to iterate over the vertices of the mesh and provides access to + * their geometric information. \note This class is not thread-safe. */ class MeshExport MeshPointIterator { public: - /** @name Construction */ - //@{ - inline explicit MeshPointIterator (const MeshKernel &rclM); - inline MeshPointIterator (const MeshKernel &rclM, PointIndex ulPos); - inline MeshPointIterator (const MeshPointIterator &rclI); - //@} + /** @name Construction */ + //@{ + inline explicit MeshPointIterator(const MeshKernel& rclM); + inline MeshPointIterator(const MeshKernel& rclM, PointIndex ulPos); + inline MeshPointIterator(const MeshPointIterator& rclI); + //@} - /** @name Transformation */ - //@{ - /// Transforms the returned points with the current transformation - inline void Transform( const Base::Matrix4D& rclTrf ); - //@} + /** @name Transformation */ + //@{ + /// Transforms the returned points with the current transformation + inline void Transform(const Base::Matrix4D& rclTrf); + //@} - /** @name Access methods */ - //@{ - /// Access to the element the iterator points to. - const MeshPoint& operator*() const - { return Dereference(); } - /// Access to the element the iterator points to. - const MeshPoint* operator->() const - { return &Dereference(); } - /// Increments the iterator. It points then to the next element if the - /// end is not reached. - const MeshPointIterator& operator ++ () - { ++_clIter; return *this; } - /// Decrements the iterator. It points then to the previous element if the beginning - /// is not reached. - const MeshPointIterator& operator -- () - { --_clIter; return *this; } - /// Assignment. - inline MeshPointIterator& operator = (const MeshPointIterator &rpI); - /// Compares if this iterator points to a lower element than the other one. - bool operator < (const MeshPointIterator &rclI) const - { return _clIter < rclI._clIter; } - /// Compares if this iterator points to a higher element than the other one. - bool operator > (const MeshPointIterator &rclI) const - { return _clIter > rclI._clIter; } - /// Checks if the iterators points to the same element. - bool operator == (const MeshPointIterator &rclI) const - { return _clIter == rclI._clIter; } - /// Sets the iterator to the beginning of the array. - void Begin () - { _clIter = _rclPAry.begin(); } - /// Sets the iterator to the end of the array. - void End () - { _clIter = _rclPAry.end(); } - /// Returns the current position of the iterator in the array. - PointIndex Position () const - { return _clIter - _rclPAry.begin(); } - /// Checks if the end is already reached. - bool EndReached () const - { return !(_clIter < _rclPAry.end()); } - /// Sets the iterator to the beginning of the array. - void Init () - { Begin(); } - /// Checks if the end is not yet reached. - bool More () const - { return !EndReached(); } - /// Increments the iterator. - void Next () - { operator++(); } - /// Sets the iterator to a given position. - inline bool Set (PointIndex ulIndex); - /// Checks if the iterator points to a valid element inside the array. - inline bool IsValid () const - { return (_clIter >= _rclPAry.begin()) && (_clIter < _rclPAry.end()); } - //@} - /** @name Flag state - */ - //@{ - void SetFlag (MeshPoint::TFlagType tF) const - { this->_clIter->SetFlag(tF); } - void ResetFlag (MeshPoint::TFlagType tF) const - { this->_clIter->ResetFlag(tF); } - bool IsFlag (MeshPoint::TFlagType tF) const - { return this->_clIter->IsFlag(tF); } - void SetProperty(unsigned long uP) const - { this->_clIter->SetProperty(uP); } - //@} + /** @name Access methods */ + //@{ + /// Access to the element the iterator points to. + const MeshPoint& operator*() const + { + return Dereference(); + } + /// Access to the element the iterator points to. + const MeshPoint* operator->() const + { + return &Dereference(); + } + /// Increments the iterator. It points then to the next element if the + /// end is not reached. + const MeshPointIterator& operator++() + { + ++_clIter; + return *this; + } + /// Decrements the iterator. It points then to the previous element if the beginning + /// is not reached. + const MeshPointIterator& operator--() + { + --_clIter; + return *this; + } + /// Assignment. + inline MeshPointIterator& operator=(const MeshPointIterator& rpI); + /// Compares if this iterator points to a lower element than the other one. + bool operator<(const MeshPointIterator& rclI) const + { + return _clIter < rclI._clIter; + } + /// Compares if this iterator points to a higher element than the other one. + bool operator>(const MeshPointIterator& rclI) const + { + return _clIter > rclI._clIter; + } + /// Checks if the iterators points to the same element. + bool operator==(const MeshPointIterator& rclI) const + { + return _clIter == rclI._clIter; + } + /// Sets the iterator to the beginning of the array. + void Begin() + { + _clIter = _rclPAry.begin(); + } + /// Sets the iterator to the end of the array. + void End() + { + _clIter = _rclPAry.end(); + } + /// Returns the current position of the iterator in the array. + PointIndex Position() const + { + return _clIter - _rclPAry.begin(); + } + /// Checks if the end is already reached. + bool EndReached() const + { + return !(_clIter < _rclPAry.end()); + } + /// Sets the iterator to the beginning of the array. + void Init() + { + Begin(); + } + /// Checks if the end is not yet reached. + bool More() const + { + return !EndReached(); + } + /// Increments the iterator. + void Next() + { + operator++(); + } + /// Sets the iterator to a given position. + inline bool Set(PointIndex ulIndex); + /// Checks if the iterator points to a valid element inside the array. + inline bool IsValid() const + { + return (_clIter >= _rclPAry.begin()) && (_clIter < _rclPAry.end()); + } + //@} + /** @name Flag state + */ + //@{ + void SetFlag(MeshPoint::TFlagType tF) const + { + this->_clIter->SetFlag(tF); + } + void ResetFlag(MeshPoint::TFlagType tF) const + { + this->_clIter->ResetFlag(tF); + } + bool IsFlag(MeshPoint::TFlagType tF) const + { + return this->_clIter->IsFlag(tF); + } + void SetProperty(unsigned long uP) const + { + this->_clIter->SetProperty(uP); + } + //@} protected: - inline const MeshPoint& Dereference () const; + inline const MeshPoint& Dereference() const; protected: - const MeshKernel& _rclMesh; - const MeshPointArray& _rclPAry; - mutable MeshPoint _clPoint; - MeshPointArray::_TConstIterator _clIter; - bool _bApply; - Base::Matrix4D _clTrf; + const MeshKernel& _rclMesh; + const MeshPointArray& _rclPAry; + mutable MeshPoint _clPoint; + MeshPointArray::_TConstIterator _clIter; + bool _bApply; + Base::Matrix4D _clTrf; - // friends - friend class MeshKernel; + // friends + friend class MeshKernel; }; class MeshFastFacetIterator { public: - inline explicit MeshFastFacetIterator (const MeshKernel &rclM); - virtual ~MeshFastFacetIterator () = default; + inline explicit MeshFastFacetIterator(const MeshKernel& rclM); + virtual ~MeshFastFacetIterator() = default; - void Init () { _clIter = _rclFAry.begin(); } - inline void Next (); - bool More () { return _clIter != _rclFAry.end(); } + void Init() + { + _clIter = _rclFAry.begin(); + } + inline void Next(); + bool More() + { + return _clIter != _rclFAry.end(); + } - Base::Vector3f _afPoints[3]; + Base::Vector3f _afPoints[3]; protected: - const MeshKernel& _rclMesh; - const MeshFacetArray& _rclFAry; - const MeshPointArray& _rclPAry; - MeshFacetArray::_TConstIterator _clIter; + const MeshKernel& _rclMesh; + const MeshFacetArray& _rclFAry; + const MeshPointArray& _rclPAry; + MeshFacetArray::_TConstIterator _clIter; public: - MeshFastFacetIterator (const MeshFastFacetIterator&) = delete; - void operator = (const MeshFastFacetIterator&) = delete; + MeshFastFacetIterator(const MeshFastFacetIterator&) = delete; + void operator=(const MeshFastFacetIterator&) = delete; }; -inline MeshFastFacetIterator::MeshFastFacetIterator (const MeshKernel &rclM) -: _rclMesh(rclM), - _rclFAry(rclM._aclFacetArray), - _rclPAry(rclM._aclPointArray), - _clIter(_rclFAry.begin()) +inline MeshFastFacetIterator::MeshFastFacetIterator(const MeshKernel& rclM) + : _rclMesh(rclM) + , _rclFAry(rclM._aclFacetArray) + , _rclPAry(rclM._aclPointArray) + , _clIter(_rclFAry.begin()) +{} + +inline void MeshFastFacetIterator::Next() { + const PointIndex* paulPt = _clIter->_aulPoints; + Base::Vector3f* pfPt = _afPoints; + *(pfPt++) = _rclPAry[*(paulPt++)]; + *(pfPt++) = _rclPAry[*(paulPt++)]; + *pfPt = _rclPAry[*paulPt]; } -inline void MeshFastFacetIterator::Next () +inline MeshFacetIterator::MeshFacetIterator(const MeshKernel& rclM) + : _rclMesh(rclM) + , _rclFAry(rclM._aclFacetArray) + , _rclPAry(rclM._aclPointArray) + , _clIter(rclM._aclFacetArray.begin()) + , _bApply(false) +{} + +inline MeshFacetIterator::MeshFacetIterator(const MeshKernel& rclM, FacetIndex ulPos) + : _rclMesh(rclM) + , _rclFAry(rclM._aclFacetArray) + , _rclPAry(rclM._aclPointArray) + , _clIter(rclM._aclFacetArray.begin() + ulPos) + , _bApply(false) +{} + +inline MeshFacetIterator::MeshFacetIterator(const MeshFacetIterator& rclI) + : _rclMesh(rclI._rclMesh) + , _rclFAry(rclI._rclFAry) + , _rclPAry(rclI._rclPAry) + , _clIter(rclI._clIter) + , _bApply(rclI._bApply) + , _clTrf(rclI._clTrf) +{} + +inline void MeshFacetIterator::Transform(const Base::Matrix4D& rclTrf) { - const PointIndex *paulPt = _clIter->_aulPoints; - Base::Vector3f *pfPt = _afPoints; - *(pfPt++) = _rclPAry[*(paulPt++)]; - *(pfPt++) = _rclPAry[*(paulPt++)]; - *pfPt = _rclPAry[*paulPt]; + _clTrf = rclTrf; + Base::Matrix4D tmp; + // checks for unit matrix + _clTrf != tmp ? _bApply = true : _bApply = false; } -inline MeshFacetIterator::MeshFacetIterator (const MeshKernel &rclM) -: _rclMesh(rclM), - _rclFAry(rclM._aclFacetArray), - _rclPAry(rclM._aclPointArray), - _clIter(rclM._aclFacetArray.begin()), - _bApply(false) +inline const MeshGeomFacet& MeshFacetIterator::Dereference() { + MeshFacet rclF = *_clIter; + const PointIndex* paulPt = &(_clIter->_aulPoints[0]); + Base::Vector3f* pclPt = _clFacet._aclPoints; + *(pclPt++) = _rclPAry[*(paulPt++)]; + *(pclPt++) = _rclPAry[*(paulPt++)]; + *pclPt = _rclPAry[*paulPt]; + _clFacet._ulProp = rclF._ulProp; + _clFacet._ucFlag = rclF._ucFlag; + _clFacet.NormalInvalid(); + if (_bApply) { + _clFacet._aclPoints[0] = _clTrf * _clFacet._aclPoints[0]; + _clFacet._aclPoints[1] = _clTrf * _clFacet._aclPoints[1]; + _clFacet._aclPoints[2] = _clTrf * _clFacet._aclPoints[2]; + } + return _clFacet; } -inline MeshFacetIterator::MeshFacetIterator (const MeshKernel &rclM, FacetIndex ulPos) -: _rclMesh(rclM), - _rclFAry(rclM._aclFacetArray), - _rclPAry(rclM._aclPointArray), - _clIter(rclM._aclFacetArray.begin() + ulPos), - _bApply(false) +inline bool MeshFacetIterator::Set(FacetIndex ulIndex) { + if (ulIndex < _rclFAry.size()) { + _clIter = _rclFAry.begin() + ulIndex; + return true; + } + else { + _clIter = _rclFAry.end(); + return false; + } } -inline MeshFacetIterator::MeshFacetIterator (const MeshFacetIterator &rclI) -: _rclMesh(rclI._rclMesh), - _rclFAry(rclI._rclFAry), - _rclPAry(rclI._rclPAry), - _clIter(rclI._clIter), - _bApply(rclI._bApply), - _clTrf(rclI._clTrf) +inline MeshFacetIterator& MeshFacetIterator::operator=(const MeshFacetIterator& rpI) { + _clIter = rpI._clIter; + _bApply = rpI._bApply; + _clTrf = rpI._clTrf; + return *this; } -inline void MeshFacetIterator::Transform( const Base::Matrix4D& rclTrf ) +inline unsigned long MeshFacetIterator::GetProperty() const { - _clTrf = rclTrf; - Base::Matrix4D tmp; - // checks for unit matrix - _clTrf != tmp ? _bApply = true : _bApply = false; + return _clIter->_ulProp; } -inline const MeshGeomFacet& MeshFacetIterator::Dereference () +inline void MeshFacetIterator::GetNeighbours(MeshFacetIterator& rclN0, + MeshFacetIterator& rclN1, + MeshFacetIterator& rclN2) const { - MeshFacet rclF = *_clIter; - const PointIndex *paulPt = &(_clIter->_aulPoints[0]); - Base::Vector3f *pclPt = _clFacet._aclPoints; - *(pclPt++) = _rclPAry[*(paulPt++)]; - *(pclPt++) = _rclPAry[*(paulPt++)]; - *pclPt = _rclPAry[*paulPt]; - _clFacet._ulProp = rclF._ulProp; - _clFacet._ucFlag = rclF._ucFlag; - _clFacet.NormalInvalid(); - if ( _bApply ) - { - _clFacet._aclPoints[0] = _clTrf * _clFacet._aclPoints[0]; - _clFacet._aclPoints[1] = _clTrf * _clFacet._aclPoints[1]; - _clFacet._aclPoints[2] = _clTrf * _clFacet._aclPoints[2]; - } - return _clFacet; + if (_clIter->_aulNeighbours[0] != FACET_INDEX_MAX) { + rclN0.Set(_clIter->_aulNeighbours[0]); + } + else { + rclN0.End(); + } + + if (_clIter->_aulNeighbours[1] != FACET_INDEX_MAX) { + rclN1.Set(_clIter->_aulNeighbours[1]); + } + else { + rclN1.End(); + } + + if (_clIter->_aulNeighbours[2] != FACET_INDEX_MAX) { + rclN2.Set(_clIter->_aulNeighbours[2]); + } + else { + rclN2.End(); + } } -inline bool MeshFacetIterator::Set (FacetIndex ulIndex) +inline void MeshFacetIterator::SetToNeighbour(unsigned short usN) { - if (ulIndex < _rclFAry.size()) - { - _clIter = _rclFAry.begin() + ulIndex; - return true; - } - else - { - _clIter = _rclFAry.end(); - return false; - } + if (_clIter->_aulNeighbours[usN] != FACET_INDEX_MAX) { + _clIter = _rclFAry.begin() + _clIter->_aulNeighbours[usN]; + } + else { + End(); + } } -inline MeshFacetIterator& MeshFacetIterator::operator = (const MeshFacetIterator &rpI) +inline MeshPointIterator::MeshPointIterator(const MeshKernel& rclM) + : _rclMesh(rclM) + , _rclPAry(_rclMesh._aclPointArray) + , _bApply(false) { - _clIter = rpI._clIter; - _bApply = rpI._bApply; - _clTrf = rpI._clTrf; - return *this; + _clIter = _rclPAry.begin(); } -inline unsigned long MeshFacetIterator::GetProperty () const +inline MeshPointIterator::MeshPointIterator(const MeshKernel& rclM, PointIndex ulPos) + : _rclMesh(rclM) + , _rclPAry(_rclMesh._aclPointArray) + , _bApply(false) { - return _clIter->_ulProp; + _clIter = _rclPAry.begin() + ulPos; } -inline void MeshFacetIterator::GetNeighbours (MeshFacetIterator &rclN0, MeshFacetIterator &rclN1, MeshFacetIterator &rclN2) const +inline MeshPointIterator::MeshPointIterator(const MeshPointIterator& rclI) + : _rclMesh(rclI._rclMesh) + , _rclPAry(rclI._rclPAry) + , _clIter(rclI._clIter) + , _bApply(rclI._bApply) + , _clTrf(rclI._clTrf) +{} + +inline void MeshPointIterator::Transform(const Base::Matrix4D& rclTrf) { - if (_clIter->_aulNeighbours[0] != FACET_INDEX_MAX) - rclN0.Set(_clIter->_aulNeighbours[0]); - else - rclN0.End(); - - if (_clIter->_aulNeighbours[1] != FACET_INDEX_MAX) - rclN1.Set(_clIter->_aulNeighbours[1]); - else - rclN1.End(); - - if (_clIter->_aulNeighbours[2] != FACET_INDEX_MAX) - rclN2.Set(_clIter->_aulNeighbours[2]); - else - rclN2.End(); + _clTrf = rclTrf; + Base::Matrix4D tmp; + // checks for unit matrix + _clTrf != tmp ? _bApply = true : _bApply = false; } -inline void MeshFacetIterator::SetToNeighbour (unsigned short usN) +inline const MeshPoint& MeshPointIterator::Dereference() const { - if (_clIter->_aulNeighbours[usN] != FACET_INDEX_MAX) - _clIter = _rclFAry.begin() + _clIter->_aulNeighbours[usN]; - else - End(); + // We change only the value of the point but not the actual iterator + _clPoint = *_clIter; + if (_bApply) { + _clPoint = _clTrf * _clPoint; + } + return _clPoint; } -inline MeshPointIterator::MeshPointIterator (const MeshKernel &rclM) -: _rclMesh(rclM), _rclPAry(_rclMesh._aclPointArray), _bApply(false) +inline bool MeshPointIterator::Set(PointIndex ulIndex) { - _clIter = _rclPAry.begin(); + if (ulIndex < _rclPAry.size()) { + _clIter = _rclPAry.begin() + ulIndex; + return true; + } + else { + _clIter = _rclPAry.end(); + return false; + } } -inline MeshPointIterator::MeshPointIterator (const MeshKernel &rclM, PointIndex ulPos) -: _rclMesh(rclM), _rclPAry(_rclMesh._aclPointArray), _bApply(false) +inline MeshPointIterator& MeshPointIterator::operator=(const MeshPointIterator& rpI) { - _clIter = _rclPAry.begin() + ulPos; -} - -inline MeshPointIterator::MeshPointIterator (const MeshPointIterator &rclI) -: _rclMesh(rclI._rclMesh), _rclPAry(rclI._rclPAry), _clIter(rclI._clIter), _bApply(rclI._bApply), _clTrf(rclI._clTrf) -{ -} - -inline void MeshPointIterator::Transform( const Base::Matrix4D& rclTrf ) -{ - _clTrf = rclTrf; - Base::Matrix4D tmp; - // checks for unit matrix - _clTrf != tmp ? _bApply = true : _bApply = false; -} - -inline const MeshPoint& MeshPointIterator::Dereference () const -{ - // We change only the value of the point but not the actual iterator - _clPoint = *_clIter; - if ( _bApply ) - _clPoint = _clTrf * _clPoint; - return _clPoint; -} - -inline bool MeshPointIterator::Set (PointIndex ulIndex) -{ - if (ulIndex < _rclPAry.size()) - { - _clIter = _rclPAry.begin() + ulIndex; - return true; - } - else - { - _clIter = _rclPAry.end(); - return false; - } -} - -inline MeshPointIterator& MeshPointIterator::operator = (const MeshPointIterator &rpI) -{ - _clIter = rpI._clIter; - _bApply = rpI._bApply; - _clTrf = rpI._clTrf; - return *this; + _clIter = rpI._clIter; + _bApply = rpI._bApply; + _clTrf = rpI._clTrf; + return *this; } -} // namespace MeshCore +} // namespace MeshCore -#endif // MESH_ITERATOR_H +#endif // MESH_ITERATOR_H diff --git a/src/Mod/Mesh/App/Core/KDTree.cpp b/src/Mod/Mesh/App/Core/KDTree.cpp index e7c50a88c9..9e262454b4 100644 --- a/src/Mod/Mesh/App/Core/KDTree.cpp +++ b/src/Mod/Mesh/App/Core/KDTree.cpp @@ -22,57 +22,59 @@ #include "PreCompiled.h" #ifdef _MSC_VER -# pragma warning(disable : 4396) +#pragma warning(disable : 4396) #endif -#include #include "KDTree.h" +#include using namespace MeshCore; struct Point3d { - using value_type = float; + using value_type = float; - Point3d(const Base::Vector3f& f, PointIndex i) : p(f), i(i) - { - } + Point3d(const Base::Vector3f& f, PointIndex i) + : p(f) + , i(i) + {} - Point3d(const Point3d& pnt) = default; + Point3d(const Point3d& pnt) = default; - Point3d(Point3d&& pnt) : p(pnt.p), i(pnt.i) - { - } + Point3d(Point3d&& pnt) + : p(pnt.p) + , i(pnt.i) + {} - ~Point3d() = default; + ~Point3d() = default; - inline value_type operator[](const int N) const - { - return p[N]; - } + inline value_type operator[](const int N) const + { + return p[N]; + } - inline bool operator==(const Point3d& other) const - { - return (this->p) == (other.p); - } + inline bool operator==(const Point3d& other) const + { + return (this->p) == (other.p); + } - inline bool operator!=(const Point3d& other) const - { - return (this->p) != (other.p); - } + inline bool operator!=(const Point3d& other) const + { + return (this->p) != (other.p); + } - inline Point3d& operator=(const Point3d& other) = default; + inline Point3d& operator=(const Point3d& other) = default; - inline Point3d& operator=(Point3d&& other) - { - this->p = other.p; - this->i = other.i; - return *this; - } + inline Point3d& operator=(Point3d&& other) + { + this->p = other.p; + this->i = other.i; + return *this; + } - Base::Vector3f p; - PointIndex i; + Base::Vector3f p; + PointIndex i; }; using MyKDTree = KDTree::KDTree<3, Point3d>; @@ -83,22 +85,24 @@ public: MyKDTree kd_tree; }; -MeshKDTree::MeshKDTree() : d(new Private) -{ -} +MeshKDTree::MeshKDTree() + : d(new Private) +{} -MeshKDTree::MeshKDTree(const std::vector& points) : d(new Private) +MeshKDTree::MeshKDTree(const std::vector& points) + : d(new Private) { - PointIndex index=0; + PointIndex index = 0; for (auto it : points) { d->kd_tree.insert(Point3d(it, index++)); } } -MeshKDTree::MeshKDTree(const MeshPointArray& points) : d(new Private) +MeshKDTree::MeshKDTree(const MeshPointArray& points) + : d(new Private) { - PointIndex index=0; - for (const auto & it : points) { + PointIndex index = 0; + for (const auto& it : points) { d->kd_tree.insert(Point3d(it, index++)); } } @@ -110,13 +114,13 @@ MeshKDTree::~MeshKDTree() void MeshKDTree::AddPoint(const Base::Vector3f& point) { - PointIndex index=d->kd_tree.size(); + PointIndex index = d->kd_tree.size(); d->kd_tree.insert(Point3d(point, index)); } void MeshKDTree::AddPoints(const std::vector& points) { - PointIndex index=d->kd_tree.size(); + PointIndex index = d->kd_tree.size(); for (auto it : points) { d->kd_tree.insert(Point3d(it, index++)); } @@ -124,8 +128,8 @@ void MeshKDTree::AddPoints(const std::vector& points) void MeshKDTree::AddPoints(const MeshPointArray& points) { - PointIndex index=d->kd_tree.size(); - for (const auto & it : points) { + PointIndex index = d->kd_tree.size(); + for (const auto& it : points) { d->kd_tree.insert(Point3d(it, index++)); } } @@ -148,22 +152,26 @@ void MeshKDTree::Optimize() PointIndex MeshKDTree::FindNearest(const Base::Vector3f& p, Base::Vector3f& n, float& dist) const { std::pair it = - d->kd_tree.find_nearest(Point3d(p,0)); - if (it.first == d->kd_tree.end()) + d->kd_tree.find_nearest(Point3d(p, 0)); + if (it.first == d->kd_tree.end()) { return POINT_INDEX_MAX; + } PointIndex index = it.first->i; n = it.first->p; dist = it.second; return index; } -PointIndex MeshKDTree::FindNearest(const Base::Vector3f& p, float max_dist, - Base::Vector3f& n, float& dist) const +PointIndex MeshKDTree::FindNearest(const Base::Vector3f& p, + float max_dist, + Base::Vector3f& n, + float& dist) const { std::pair it = - d->kd_tree.find_nearest(Point3d(p,0), max_dist); - if (it.first == d->kd_tree.end()) + d->kd_tree.find_nearest(Point3d(p, 0), max_dist); + if (it.first == d->kd_tree.end()) { return POINT_INDEX_MAX; + } PointIndex index = it.first->i; n = it.first->p; dist = it.second; @@ -172,19 +180,22 @@ PointIndex MeshKDTree::FindNearest(const Base::Vector3f& p, float max_dist, PointIndex MeshKDTree::FindExact(const Base::Vector3f& p) const { - MyKDTree::const_iterator it = - d->kd_tree.find_exact(Point3d(p,0)); - if (it == d->kd_tree.end()) + MyKDTree::const_iterator it = d->kd_tree.find_exact(Point3d(p, 0)); + if (it == d->kd_tree.end()) { return POINT_INDEX_MAX; + } PointIndex index = it->i; return index; } -void MeshKDTree::FindInRange(const Base::Vector3f& p, float range, std::vector& indices) const +void MeshKDTree::FindInRange(const Base::Vector3f& p, + float range, + std::vector& indices) const { std::vector v; - d->kd_tree.find_within_range(Point3d(p,0), range, std::back_inserter(v)); + d->kd_tree.find_within_range(Point3d(p, 0), range, std::back_inserter(v)); indices.reserve(v.size()); - for (const auto & it : v) + for (const auto& it : v) { indices.push_back(it.i); + } } diff --git a/src/Mod/Mesh/App/Core/KDTree.h b/src/Mod/Mesh/App/Core/KDTree.h index fbe74c2254..4116cf6915 100644 --- a/src/Mod/Mesh/App/Core/KDTree.h +++ b/src/Mod/Mesh/App/Core/KDTree.h @@ -46,8 +46,8 @@ public: void Optimize(); PointIndex FindNearest(const Base::Vector3f& p, Base::Vector3f& n, float&) const; - PointIndex FindNearest(const Base::Vector3f& p, float max_dist, - Base::Vector3f& n, float&) const; + PointIndex + FindNearest(const Base::Vector3f& p, float max_dist, Base::Vector3f& n, float&) const; PointIndex FindExact(const Base::Vector3f& p) const; void FindInRange(const Base::Vector3f&, float, std::vector&) const; @@ -57,10 +57,10 @@ private: public: MeshKDTree(const MeshKDTree&) = delete; - void operator= (const MeshKDTree&) = delete; + void operator=(const MeshKDTree&) = delete; }; -} // namespace MeshCore +} // namespace MeshCore #endif // MESH_KDTREE_H diff --git a/src/Mod/Mesh/App/Core/MeshIO.cpp b/src/Mod/Mesh/App/Core/MeshIO.cpp index fc090c0c1a..9f3319e2ad 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.cpp +++ b/src/Mod/Mesh/App/Core/MeshIO.cpp @@ -23,11 +23,11 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include #endif #include @@ -36,6 +36,11 @@ #include #include +#include "IO/Reader3MF.h" +#include "IO/ReaderOBJ.h" +#include "IO/Writer3MF.h" +#include "IO/WriterInventor.h" +#include "IO/WriterOBJ.h" #include #include #include @@ -46,36 +51,34 @@ #include #include #include -#include "IO/Reader3MF.h" -#include "IO/ReaderOBJ.h" -#include "IO/Writer3MF.h" -#include "IO/WriterInventor.h" -#include "IO/WriterOBJ.h" #include #include -#include "MeshIO.h" #include "Builder.h" #include "Definitions.h" #include "Degeneration.h" #include "Iterator.h" +#include "MeshIO.h" #include "MeshKernel.h" using namespace MeshCore; -namespace MeshCore { +namespace MeshCore +{ std::string& ltrim(std::string& str) { - std::string::size_type pos=0; + std::string::size_type pos = 0; for (char it : str) { - if (it != 0x20 && it != 0x09) + if (it != 0x20 && it != 0x09) { break; + } pos++; } - if (pos > 0) + if (pos > 0) { str = str.substr(pos); + } return str; } @@ -92,34 +95,50 @@ int numDigits(int number) } /* Usage by CMeshNastran, CMeshCadmouldFE. Added by Sergey Sukhov (26.04.2002)*/ -struct NODE {float x, y, z;}; -struct TRIA {int iV[3];}; -struct QUAD {int iV[4];}; +struct NODE +{ + float x, y, z; +}; +struct TRIA +{ + int iV[3]; +}; +struct QUAD +{ + int iV[4]; +}; -} +} // namespace MeshCore // -------------------------------------------------------------- -bool Material::operator == (const Material& mat) const +bool Material::operator==(const Material& mat) const { - if (binding != mat.binding) + if (binding != mat.binding) { return false; - if (ambientColor != mat.ambientColor) + } + if (ambientColor != mat.ambientColor) { return false; - if (diffuseColor != mat.diffuseColor) + } + if (diffuseColor != mat.diffuseColor) { return false; - if (specularColor != mat.specularColor) + } + if (specularColor != mat.specularColor) { return false; - if (emissiveColor != mat.emissiveColor) + } + if (emissiveColor != mat.emissiveColor) { return false; - if (shininess != mat.shininess) + } + if (shininess != mat.shininess) { return false; - if (transparency != mat.transparency) + } + if (transparency != mat.transparency) { return false; + } return true; } -bool Material::operator != (const Material& mat) const +bool Material::operator!=(const Material& mat) const { return !operator==(mat); } @@ -143,41 +162,43 @@ std::vector MeshInput::supportedMeshFormats() MeshIO::Format MeshInput::getFormat(const char* FileName) { - Base::FileInfo fi(FileName); - if (fi.hasExtension("bms")) { - return MeshIO::Format::BMS; - } - else if (fi.hasExtension("ply")) { - return MeshIO::Format::PLY; - } - else if (fi.hasExtension("stl")) { - return MeshIO::Format::STL; - } - else if (fi.hasExtension("ast")) { - return MeshIO::Format::ASTL; - } - else if (fi.hasExtension("obj")) { - return MeshIO::Format::OBJ; - } - else if (fi.hasExtension("off")) { - return MeshIO::Format::OFF; - } - else if (fi.hasExtension("smf")) { - return MeshIO::Format::SMF; - } - else { - throw Base::FileException("File extension not supported", FileName); - } + Base::FileInfo fi(FileName); + if (fi.hasExtension("bms")) { + return MeshIO::Format::BMS; + } + else if (fi.hasExtension("ply")) { + return MeshIO::Format::PLY; + } + else if (fi.hasExtension("stl")) { + return MeshIO::Format::STL; + } + else if (fi.hasExtension("ast")) { + return MeshIO::Format::ASTL; + } + else if (fi.hasExtension("obj")) { + return MeshIO::Format::OBJ; + } + else if (fi.hasExtension("off")) { + return MeshIO::Format::OFF; + } + else if (fi.hasExtension("smf")) { + return MeshIO::Format::SMF; + } + else { + throw Base::FileException("File extension not supported", FileName); + } } bool MeshInput::LoadAny(const char* FileName) { // ask for read permission Base::FileInfo fi(FileName); - if (!fi.exists() || !fi.isFile()) + if (!fi.exists() || !fi.isFile()) { throw Base::FileException("File does not exist", FileName); - if (!fi.isReadable()) + } + if (!fi.isReadable()) { throw Base::FileException("No permission on the file", FileName); + } Base::ifstream str(fi, std::ios::in | std::ios::binary); @@ -192,27 +213,28 @@ bool MeshInput::LoadAny(const char* FileName) ok = LoadSTL(str); } else if (fi.hasExtension("iv")) { - ok = LoadInventor( str ); - if (ok && _rclMesh.CountFacets() == 0) + ok = LoadInventor(str); + if (ok && _rclMesh.CountFacets() == 0) { Base::Console().Warning("No usable mesh found in file '%s'", FileName); + } } else if (fi.hasExtension({"nas", "bdf"})) { - ok = LoadNastran( str ); + ok = LoadNastran(str); } else if (fi.hasExtension("obj")) { - ok = LoadOBJ( str, FileName ); + ok = LoadOBJ(str, FileName); } else if (fi.hasExtension("smf")) { - ok = LoadSMF( str ); + ok = LoadSMF(str); } else if (fi.hasExtension("3mf")) { - ok = Load3MF( str ); + ok = Load3MF(str); } else if (fi.hasExtension("off")) { - ok = LoadOFF( str ); + ok = LoadOFF(str); } else if (fi.hasExtension("ply")) { - ok = LoadPLY( str ); + ok = LoadPLY(str); } else { throw Base::FileException("File extension not supported", FileName); @@ -222,71 +244,77 @@ bool MeshInput::LoadAny(const char* FileName) } } -bool MeshInput::LoadFormat(std::istream &str, MeshIO::Format fmt) +bool MeshInput::LoadFormat(std::istream& str, MeshIO::Format fmt) { switch (fmt) { - case MeshIO::BMS: - _rclMesh.Read(str); - return true; - case MeshIO::APLY: - case MeshIO::PLY: - return LoadPLY(str); - case MeshIO::ASTL: - return LoadAsciiSTL(str); - case MeshIO::BSTL: - return LoadBinarySTL(str); - case MeshIO::STL: - return LoadSTL(str); - case MeshIO::OBJ: - return LoadOBJ(str); - case MeshIO::SMF: - return LoadSMF(str); - case MeshIO::ThreeMF: - return Load3MF(str); - case MeshIO::OFF: - return LoadOFF(str); - case MeshIO::IV: - return LoadInventor(str); - case MeshIO::NAS: - return LoadNastran(str); - default: - throw Base::FileException("Unsupported file format"); + case MeshIO::BMS: + _rclMesh.Read(str); + return true; + case MeshIO::APLY: + case MeshIO::PLY: + return LoadPLY(str); + case MeshIO::ASTL: + return LoadAsciiSTL(str); + case MeshIO::BSTL: + return LoadBinarySTL(str); + case MeshIO::STL: + return LoadSTL(str); + case MeshIO::OBJ: + return LoadOBJ(str); + case MeshIO::SMF: + return LoadSMF(str); + case MeshIO::ThreeMF: + return Load3MF(str); + case MeshIO::OFF: + return LoadOFF(str); + case MeshIO::IV: + return LoadInventor(str); + case MeshIO::NAS: + return LoadNastran(str); + default: + throw Base::FileException("Unsupported file format"); } } /** Loads an STL file either in binary or ASCII format. * Therefore the file header gets checked to decide if the file is binary or not. */ -bool MeshInput::LoadSTL (std::istream &rstrIn) +bool MeshInput::LoadSTL(std::istream& rstrIn) { char szBuf[200]; - if (!rstrIn || rstrIn.bad()) + if (!rstrIn || rstrIn.bad()) { return false; + } - // Read in 50 characters from position 80 on and check for keywords like 'SOLID', 'FACET', 'NORMAL', - // 'VERTEX', 'ENDFACET' or 'ENDLOOP'. - // As the file can be binary with one triangle only we must not read in more than (max.) 54 bytes because - // the file size has only 134 bytes in this case. On the other hand we must overread the first 80 bytes - // because it can happen that the file is binary but contains one of these keywords. + // Read in 50 characters from position 80 on and check for keywords like 'SOLID', 'FACET', + // 'NORMAL', 'VERTEX', 'ENDFACET' or 'ENDLOOP'. As the file can be binary with one triangle only + // we must not read in more than (max.) 54 bytes because the file size has only 134 bytes in + // this case. On the other hand we must overread the first 80 bytes because it can happen that + // the file is binary but contains one of these keywords. std::streambuf* buf = rstrIn.rdbuf(); - if (!buf) + if (!buf) { return false; + } buf->pubseekoff(80, std::ios::beg, std::ios::in); - uint32_t ulCt, ulBytes=50; + uint32_t ulCt, ulBytes = 50; rstrIn.read((char*)&ulCt, sizeof(ulCt)); // if we have a binary STL with a single triangle we can only read-in 50 bytes - if (ulCt > 1) + if (ulCt > 1) { ulBytes = 100; - // Either it's really an invalid STL file or it's just empty. In this case the number of facets must be 0. - if (!rstrIn.read(szBuf, ulBytes)) - return (ulCt==0); + } + // Either it's really an invalid STL file or it's just empty. In this case the number of facets + // must be 0. + if (!rstrIn.read(szBuf, ulBytes)) { + return (ulCt == 0); + } szBuf[ulBytes] = 0; boost::algorithm::to_upper(szBuf); try { - if (!strstr(szBuf, "SOLID") && !strstr(szBuf, "FACET") && !strstr(szBuf, "NORMAL") && - !strstr(szBuf, "VERTEX") && !strstr(szBuf, "ENDFACET") && !strstr(szBuf, "ENDLOOP")) { + if (!strstr(szBuf, "SOLID") && !strstr(szBuf, "FACET") && !strstr(szBuf, "NORMAL") + && !strstr(szBuf, "VERTEX") && !strstr(szBuf, "ENDFACET") + && !strstr(szBuf, "ENDLOOP")) { // probably binary STL buf->pubseekoff(0, std::ios::beg, std::ios::in); return LoadBinarySTL(rstrIn); @@ -299,7 +327,7 @@ bool MeshInput::LoadSTL (std::istream &rstrIn) } catch (const Base::MemoryException&) { _rclMesh.Clear(); - throw; // Throw the same instance of Base::MemoryException + throw; // Throw the same instance of Base::MemoryException } catch (const Base::AbortException&) { _rclMesh.Clear(); @@ -318,7 +346,7 @@ bool MeshInput::LoadSTL (std::istream &rstrIn) } /** Loads an OBJ file. */ -bool MeshInput::LoadOBJ (std::istream &rstrIn) +bool MeshInput::LoadOBJ(std::istream& rstrIn) { ReaderOBJ reader(this->_rclMesh, this->_material); if (reader.Load(rstrIn)) { @@ -329,10 +357,10 @@ bool MeshInput::LoadOBJ (std::istream &rstrIn) return false; } -bool MeshInput::LoadOBJ (std::istream &str, const char* filename) +bool MeshInput::LoadOBJ(std::istream& str, const char* filename) { ReaderOBJ reader(this->_rclMesh, this->_material); - if (reader.Load( str )) { + if (reader.Load(str)) { _groupNames = reader.GetGroupNames(); if (this->_material && this->_material->binding == MeshCore::MeshIO::PER_FACE) { Base::FileInfo fi(filename); @@ -350,31 +378,33 @@ bool MeshInput::LoadOBJ (std::istream &str, const char* filename) } /** Loads an SMF file. */ -bool MeshInput::LoadSMF (std::istream &rstrIn) +bool MeshInput::LoadSMF(std::istream& rstrIn) { boost::regex rx_p("^v\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" - "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" - "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)\\s*$"); + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)\\s*$"); boost::regex rx_f3("^f\\s+([-+]?[0-9]+)" - "\\s+([-+]?[0-9]+)" - "\\s+([-+]?[0-9]+)\\s*$"); + "\\s+([-+]?[0-9]+)" + "\\s+([-+]?[0-9]+)\\s*$"); boost::cmatch what; - unsigned long segment=0; + unsigned long segment = 0; MeshPointArray meshPoints; MeshFacetArray meshFacets; std::string line; float fX, fY, fZ; - int i1=1,i2=1,i3=1; + int i1 = 1, i2 = 1, i3 = 1; MeshFacet item; - if (!rstrIn || rstrIn.bad()) + if (!rstrIn || rstrIn.bad()) { return false; + } std::streambuf* buf = rstrIn.rdbuf(); - if (!buf) + if (!buf) { return false; + } while (std::getline(rstrIn, line)) { if (boost::regex_match(line.c_str(), what, rx_p)) { @@ -386,30 +416,30 @@ bool MeshInput::LoadSMF (std::istream &rstrIn) else if (boost::regex_match(line.c_str(), what, rx_f3)) { // 3-vertex face i1 = std::atoi(what[1].first); - i1 = i1 > 0 ? i1-1 : i1+static_cast(meshPoints.size()); + i1 = i1 > 0 ? i1 - 1 : i1 + static_cast(meshPoints.size()); i2 = std::atoi(what[2].first); - i2 = i2 > 0 ? i2-1 : i2+static_cast(meshPoints.size()); + i2 = i2 > 0 ? i2 - 1 : i2 + static_cast(meshPoints.size()); i3 = std::atoi(what[3].first); - i3 = i3 > 0 ? i3-1 : i3+static_cast(meshPoints.size()); - item.SetVertices(i1,i2,i3); + i3 = i3 > 0 ? i3 - 1 : i3 + static_cast(meshPoints.size()); + item.SetVertices(i1, i2, i3); item.SetProperty(segment); meshFacets.push_back(item); } } - this->_rclMesh.Clear(); // remove all data before + this->_rclMesh.Clear(); // remove all data before - MeshCleanup meshCleanup(meshPoints,meshFacets); + MeshCleanup meshCleanup(meshPoints, meshFacets); meshCleanup.RemoveInvalids(); - MeshPointFacetAdjacency meshAdj(meshPoints.size(),meshFacets); + MeshPointFacetAdjacency meshAdj(meshPoints.size(), meshFacets); meshAdj.SetFacetNeighbourhood(); - this->_rclMesh.Adopt(meshPoints,meshFacets); + this->_rclMesh.Adopt(meshPoints, meshFacets); return true; } /** Loads an OFF file. */ -bool MeshInput::LoadOFF (std::istream &rstrIn) +bool MeshInput::LoadOFF(std::istream& rstrIn) { // http://edutechwiki.unige.ch/en/3D_file_format boost::regex rx_n(R"(^\s*([0-9]+)\s+([0-9]+)\s+([0-9]+)\s*$)"); @@ -423,12 +453,14 @@ bool MeshInput::LoadOFF (std::istream &rstrIn) std::string line; MeshFacet item; - if (!rstrIn || rstrIn.bad()) + if (!rstrIn || rstrIn.bad()) { return false; + } std::streambuf* buf = rstrIn.rdbuf(); - if (!buf) + if (!buf) { return false; + } std::getline(rstrIn, line); boost::algorithm::to_lower(line); @@ -437,11 +469,11 @@ bool MeshInput::LoadOFF (std::istream &rstrIn) colorPerVertex = true; } else if (line.find("off") == std::string::npos) { - return false; // not an OFF file + return false; // not an OFF file } // get number of vertices and faces - int numPoints=0, numFaces=0; + int numPoints = 0, numFaces = 0; while (true) { std::getline(rstrIn, line); @@ -453,25 +485,30 @@ bool MeshInput::LoadOFF (std::istream &rstrIn) } } - if (numPoints == 0 || numFaces == 0) + if (numPoints == 0 || numFaces == 0) { return false; + } meshPoints.reserve(numPoints); meshFacets.reserve(numFaces); - if (colorPerVertex) + if (colorPerVertex) { diffuseColor.reserve(numPoints); - else + } + else { diffuseColor.reserve(numFaces); + } int cntPoints = 0; while (cntPoints < numPoints) { - if (!std::getline(rstrIn, line)) + if (!std::getline(rstrIn, line)) { break; + } std::istringstream str(line); str.unsetf(std::ios_base::skipws); str >> std::ws; - if (str.eof()) - continue; // empty line + if (str.eof()) { + continue; // empty line + } float fX, fY, fZ; str >> fX >> std::ws >> fY >> std::ws >> fZ; @@ -482,19 +519,20 @@ bool MeshInput::LoadOFF (std::istream &rstrIn) if (colorPerVertex) { std::size_t pos = std::size_t(str.tellg()); if (line.size() > pos) { - float r,g,b,a; + float r, g, b, a; str >> std::ws >> r >> std::ws >> g >> std::ws >> b; if (str) { str >> std::ws >> a; // no transparency - if (!str) + if (!str) { a = 0.0f; + } if (r > 1.0f || g > 1.0f || b > 1.0f || a > 1.0f) { - r = static_cast(r)/255.0f; - g = static_cast(g)/255.0f; - b = static_cast(b)/255.0f; - a = static_cast(a)/255.0f; + r = static_cast(r) / 255.0f; + g = static_cast(g) / 255.0f; + b = static_cast(b) / 255.0f; + a = static_cast(a) / 255.0f; } diffuseColor.emplace_back(r, g, b, a); } @@ -505,13 +543,15 @@ bool MeshInput::LoadOFF (std::istream &rstrIn) int cntFaces = 0; while (cntFaces < numFaces) { - if (!std::getline(rstrIn, line)) + if (!std::getline(rstrIn, line)) { break; + } std::istringstream str(line); str.unsetf(std::ios_base::skipws); str >> std::ws; - if (str.eof()) - continue; // empty line + if (str.eof()) { + continue; // empty line + } int count, index; str >> count; if (count >= 3) { @@ -524,29 +564,30 @@ bool MeshInput::LoadOFF (std::istream &rstrIn) faces.push_back(index); } - for (int i = 0; i < count-2; i++) { - item.SetVertices(faces[0],faces[i+1],faces[i+2]); + for (int i = 0; i < count - 2; i++) { + item.SetVertices(faces[0], faces[i + 1], faces[i + 2]); meshFacets.push_back(item); } cntFaces++; std::size_t pos = std::size_t(str.tellg()); if (line.size() > pos) { - float r,g,b,a; + float r, g, b, a; str >> std::ws >> r >> std::ws >> g >> std::ws >> b; if (str) { str >> std::ws >> a; // no transparency - if (!str) + if (!str) { a = 0.0f; + } if (r > 1.0f || g > 1.0f || b > 1.0f || a > 1.0f) { - r = static_cast(r)/255.0f; - g = static_cast(g)/255.0f; - b = static_cast(b)/255.0f; - a = static_cast(a)/255.0f; + r = static_cast(r) / 255.0f; + g = static_cast(g) / 255.0f; + b = static_cast(b) / 255.0f; + a = static_cast(a) / 255.0f; } - for (int i = 0; i < count-2; i++) { + for (int i = 0; i < count - 2; i++) { diffuseColor.emplace_back(r, g, b, a); } } @@ -568,68 +609,86 @@ bool MeshInput::LoadOFF (std::istream &rstrIn) } } } - this->_rclMesh.Clear(); // remove all data before + this->_rclMesh.Clear(); // remove all data before - MeshCleanup meshCleanup(meshPoints,meshFacets); - if (_material) + MeshCleanup meshCleanup(meshPoints, meshFacets); + if (_material) { meshCleanup.SetMaterial(_material); + } meshCleanup.RemoveInvalids(); - MeshPointFacetAdjacency meshAdj(meshPoints.size(),meshFacets); + MeshPointFacetAdjacency meshAdj(meshPoints.size(), meshFacets); meshAdj.SetFacetNeighbourhood(); - this->_rclMesh.Adopt(meshPoints,meshFacets); + this->_rclMesh.Adopt(meshPoints, meshFacets); return true; } -namespace MeshCore { - namespace Ply { - enum Number { - int8, uint8, int16, uint16, int32, uint32, float32, float64 - }; - struct Property - { - using first_argument_type = std::pair; - using second_argument_type = std::string; - using result_type = bool; +namespace MeshCore +{ +namespace Ply +{ +enum Number +{ + int8, + uint8, + int16, + uint16, + int32, + uint32, + float32, + float64 +}; +struct Property +{ + using first_argument_type = std::pair; + using second_argument_type = std::string; + using result_type = bool; - bool operator()(const std::pair& x, - const std::string& y) const - { - return x.first == y; - } - }; + bool operator()(const std::pair& x, const std::string& y) const + { + return x.first == y; } - using namespace Ply; -} +}; +} // namespace Ply +using namespace Ply; +} // namespace MeshCore -bool MeshInput::LoadPLY (std::istream &inp) +bool MeshInput::LoadPLY(std::istream& inp) { // http://local.wasp.uwa.edu.au/~pbourke/dataformats/ply/ - std::size_t v_count=0, f_count=0; + std::size_t v_count = 0, f_count = 0; MeshPointArray meshPoints; MeshFacetArray meshFacets; - enum { - unknown, ascii, binary_little_endian, binary_big_endian + enum + { + unknown, + ascii, + binary_little_endian, + binary_big_endian } format = unknown; - if (!inp || inp.bad()) + if (!inp || inp.bad()) { return false; + } std::streambuf* buf = inp.rdbuf(); - if (!buf) + if (!buf) { return false; + } // read in the first three characters char ply[3]; inp.read(ply, 3); inp.ignore(1); - if (!inp) + if (!inp) { return false; - if ((ply[0] != 'p') || (ply[1] != 'l') || (ply[2] != 'y')) - return false; // wrong header + } + if ((ply[0] != 'p') || (ply[1] != 'l') || (ply[2] != 'y')) { + return false; // wrong header + } - std::vector > vertex_props; + std::vector> vertex_props; std::vector face_props; std::string line, element; @@ -638,19 +697,18 @@ bool MeshInput::LoadPLY (std::istream &inp) std::istringstream str(line); str.unsetf(std::ios_base::skipws); str >> std::ws; - if (str.eof()) - continue; // empty line + if (str.eof()) { + continue; // empty line + } std::string kw; str >> kw; if (kw == "format") { std::string format_string, version; char space_format_string, space_format_version; - str >> space_format_string >> std::ws - >> format_string >> space_format_version + str >> space_format_string >> std::ws >> format_string >> space_format_version >> std::ws >> version; if (/*!str || !str.eof() ||*/ - !std::isspace(space_format_string) || - !std::isspace(space_format_version)) { + !std::isspace(space_format_string) || !std::isspace(space_format_version)) { return false; } if (format_string == "ascii") { @@ -675,12 +733,9 @@ bool MeshInput::LoadPLY (std::istream &inp) std::string name; std::size_t count; char space_element_name, space_name_count; - str >> space_element_name >> std::ws - >> name >> space_name_count >> std::ws - >> count; + str >> space_element_name >> std::ws >> name >> space_name_count >> std::ws >> count; if (/*!str || !str.eof() ||*/ - !std::isspace(space_element_name) || - !std::isspace(space_name_count)) { + !std::isspace(space_element_name) || !std::isspace(space_name_count)) { return false; } else if (name == "vertex") { @@ -701,8 +756,7 @@ bool MeshInput::LoadPLY (std::istream &inp) std::string type, name; char space; if (element == "vertex") { - str >> space >> std::ws - >> type >> space >> std::ws >> name >> std::ws; + str >> space >> std::ws >> type >> space >> std::ws >> name >> std::ws; Ply::Number number; if (type == "char" || type == "int8") { @@ -739,11 +793,9 @@ bool MeshInput::LoadPLY (std::istream &inp) } else if (element == "face") { std::string list, uchr; - str >> space >> std::ws - >> list >> std::ws; + str >> space >> std::ws >> list >> std::ws; if (list == "list") { - str >> uchr >> std::ws - >> type >> std::ws >> name >> std::ws; + str >> uchr >> std::ws >> type >> std::ws >> name >> std::ws; } else { // not a 'list' @@ -787,46 +839,71 @@ bool MeshInput::LoadPLY (std::istream &inp) } } else if (kw == "end_header") { - break; // end of the header, now read the data + break; // end of the header, now read the data } } // check if valid 3d points Property property; - std::size_t num_x = std::count_if(vertex_props.begin(), vertex_props.end(), - [&property](const std::pair& p) { return property(p, "x"); }); - if (num_x != 1) + std::size_t num_x = std::count_if(vertex_props.begin(), + vertex_props.end(), + [&property](const std::pair& p) { + return property(p, "x"); + }); + if (num_x != 1) { return false; + } - std::size_t num_y = std::count_if(vertex_props.begin(), vertex_props.end(), - [&property](const std::pair& p) { return property(p, "y"); }); - if (num_y != 1) + std::size_t num_y = std::count_if(vertex_props.begin(), + vertex_props.end(), + [&property](const std::pair& p) { + return property(p, "y"); + }); + if (num_y != 1) { return false; + } - std::size_t num_z = std::count_if(vertex_props.begin(), vertex_props.end(), - [&property](const std::pair& p) { return property(p, "z"); }); - if (num_z != 1) + std::size_t num_z = std::count_if(vertex_props.begin(), + vertex_props.end(), + [&property](const std::pair& p) { + return property(p, "z"); + }); + if (num_z != 1) { return false; + } - for (auto & it : vertex_props) { - if (it.first == "diffuse_red") + for (auto& it : vertex_props) { + if (it.first == "diffuse_red") { it.first = "red"; - else if (it.first == "diffuse_green") + } + else if (it.first == "diffuse_green") { it.first = "green"; - else if (it.first == "diffuse_blue") + } + else if (it.first == "diffuse_blue") { it.first = "blue"; + } } // check if valid colors are set - std::size_t num_r = std::count_if(vertex_props.begin(), vertex_props.end(), - [&property](const std::pair& p) { return property(p, "red"); }); - std::size_t num_g = std::count_if(vertex_props.begin(), vertex_props.end(), - [&property](const std::pair& p) { return property(p, "green"); }); - std::size_t num_b = std::count_if(vertex_props.begin(), vertex_props.end(), - [&property](const std::pair& p) { return property(p, "blue"); }); + std::size_t num_r = std::count_if(vertex_props.begin(), + vertex_props.end(), + [&property](const std::pair& p) { + return property(p, "red"); + }); + std::size_t num_g = std::count_if(vertex_props.begin(), + vertex_props.end(), + [&property](const std::pair& p) { + return property(p, "green"); + }); + std::size_t num_b = std::count_if(vertex_props.begin(), + vertex_props.end(), + [&property](const std::pair& p) { + return property(p, "blue"); + }); std::size_t rgb_colors = num_r + num_g + num_b; - if (rgb_colors != 0 && rgb_colors != 3) + if (rgb_colors != 0 && rgb_colors != 3) { return false; + } // only if set per vertex if (rgb_colors == 3) { @@ -847,12 +924,11 @@ bool MeshInput::LoadPLY (std::istream &inp) for (std::size_t i = 0; i < v_count && std::getline(inp, line); i++) { // go through the vertex properties std::map prop_values; - for (const auto & it : vertex_props) { + for (const auto& it : vertex_props) { switch (it.second) { - case int8: - case int16: - case int32: - { + case int8: + case int16: + case int32: { if (boost::regex_search(line, what, rx_s)) { int v; v = boost::lexical_cast(what[1]); @@ -863,10 +939,9 @@ bool MeshInput::LoadPLY (std::istream &inp) return false; } } break; - case uint8: - case uint16: - case uint32: - { + case uint8: + case uint16: + case uint32: { if (boost::regex_search(line, what, rx_u)) { int v; v = boost::lexical_cast(what[1]); @@ -877,9 +952,8 @@ bool MeshInput::LoadPLY (std::istream &inp) return false; } } break; - case float32: - case float64: - { + case float32: + case float64: { if (boost::regex_search(line, what, rx_d)) { double v; v = boost::lexical_cast(what[1]); @@ -890,8 +964,8 @@ bool MeshInput::LoadPLY (std::istream &inp) return false; } } break; - default: - return false; + default: + return false; } } @@ -915,65 +989,67 @@ bool MeshInput::LoadPLY (std::istream &inp) f1 = boost::lexical_cast(what[1]); f2 = boost::lexical_cast(what[2]); f3 = boost::lexical_cast(what[3]); - meshFacets.push_back(MeshFacet(f1,f2,f3)); + meshFacets.push_back(MeshFacet(f1, f2, f3)); } } } // binary else { Base::InputStream is(inp); - if (format == binary_little_endian) + if (format == binary_little_endian) { is.setByteOrder(Base::Stream::LittleEndian); - else + } + else { is.setByteOrder(Base::Stream::BigEndian); + } for (std::size_t i = 0; i < v_count; i++) { // go through the vertex properties std::map prop_values; - for (const auto & it : vertex_props) { + for (const auto& it : vertex_props) { switch (it.second) { - case int8: - { - int8_t v; is >> v; + case int8: { + int8_t v; + is >> v; prop_values[it.first] = static_cast(v); } break; - case uint8: - { - uint8_t v; is >> v; + case uint8: { + uint8_t v; + is >> v; prop_values[it.first] = static_cast(v); } break; - case int16: - { - int16_t v; is >> v; + case int16: { + int16_t v; + is >> v; prop_values[it.first] = static_cast(v); } break; - case uint16: - { - uint16_t v; is >> v; + case uint16: { + uint16_t v; + is >> v; prop_values[it.first] = static_cast(v); } break; - case int32: - { - int32_t v; is >> v; + case int32: { + int32_t v; + is >> v; prop_values[it.first] = static_cast(v); } break; - case uint32: - { - uint32_t v; is >> v; + case uint32: { + uint32_t v; + is >> v; prop_values[it.first] = static_cast(v); } break; - case float32: - { - float v; is >> v; + case float32: { + float v; + is >> v; prop_values[it.first] = v; } break; - case float64: - { - double v; is >> v; + case float64: { + double v; + is >> v; prop_values[it.first] = static_cast(v); } break; - default: - return false; + default: + return false; } } @@ -995,72 +1071,74 @@ bool MeshInput::LoadPLY (std::istream &inp) uint32_t f1, f2, f3; for (std::size_t i = 0; i < f_count; i++) { is >> n; - if (n==3) { + if (n == 3) { is >> f1 >> f2 >> f3; - if (f1 < v_count && f2 < v_count && f3 < v_count) - meshFacets.push_back(MeshFacet(f1,f2,f3)); + if (f1 < v_count && f2 < v_count && f3 < v_count) { + meshFacets.push_back(MeshFacet(f1, f2, f3)); + } for (auto it : face_props) { switch (it) { - case int8: - { - int8_t v; is >> v; + case int8: { + int8_t v; + is >> v; } break; - case uint8: - { - uint8_t v; is >> v; + case uint8: { + uint8_t v; + is >> v; } break; - case int16: - { - int16_t v; is >> v; + case int16: { + int16_t v; + is >> v; } break; - case uint16: - { - uint16_t v; is >> v; + case uint16: { + uint16_t v; + is >> v; } break; - case int32: - { - int32_t v; is >> v; + case int32: { + int32_t v; + is >> v; } break; - case uint32: - { - uint32_t v; is >> v; + case uint32: { + uint32_t v; + is >> v; } break; - case float32: - { + case float32: { is >> n; float v; - for (unsigned char j=0; j> v; + } } break; - case float64: - { + case float64: { is >> n; double v; - for (unsigned char j=0; j> v; + } } break; - default: - return false; + default: + return false; } } } } } - this->_rclMesh.Clear(); // remove all data before + this->_rclMesh.Clear(); // remove all data before - MeshCleanup meshCleanup(meshPoints,meshFacets); - if (_material) + MeshCleanup meshCleanup(meshPoints, meshFacets); + if (_material) { meshCleanup.SetMaterial(_material); + } meshCleanup.RemoveInvalids(); - MeshPointFacetAdjacency meshAdj(meshPoints.size(),meshFacets); + MeshPointFacetAdjacency meshAdj(meshPoints.size(), meshFacets); meshAdj.SetFacetNeighbourhood(); - this->_rclMesh.Adopt(meshPoints,meshFacets); + this->_rclMesh.Adopt(meshPoints, meshFacets); return true; } -bool MeshInput::LoadMeshNode (std::istream &rstrIn) +bool MeshInput::LoadMeshNode(std::istream& rstrIn) { boost::regex rx_p("^v\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" @@ -1074,15 +1152,17 @@ bool MeshInput::LoadMeshNode (std::istream &rstrIn) std::string line; float fX, fY, fZ; - unsigned int i1=1,i2=1,i3=1; + unsigned int i1 = 1, i2 = 1, i3 = 1; MeshGeomFacet clFacet; - if (!rstrIn || rstrIn.bad()) + if (!rstrIn || rstrIn.bad()) { return false; + } std::streambuf* buf = rstrIn.rdbuf(); - if (!buf) + if (!buf) { return false; + } while (std::getline(rstrIn, line)) { boost::algorithm::to_lower(line); @@ -1096,26 +1176,26 @@ bool MeshInput::LoadMeshNode (std::istream &rstrIn) i1 = std::atoi(what[1].first); i2 = std::atoi(what[2].first); i3 = std::atoi(what[3].first); - meshFacets.push_back(MeshFacet(i1-1,i2-1,i3-1)); + meshFacets.push_back(MeshFacet(i1 - 1, i2 - 1, i3 - 1)); } else if (boost::regex_match(line.c_str(), what, rx_e)) { break; } } - this->_rclMesh.Clear(); // remove all data before + this->_rclMesh.Clear(); // remove all data before - MeshCleanup meshCleanup(meshPoints,meshFacets); + MeshCleanup meshCleanup(meshPoints, meshFacets); meshCleanup.RemoveInvalids(); - MeshPointFacetAdjacency meshAdj(meshPoints.size(),meshFacets); + MeshPointFacetAdjacency meshAdj(meshPoints.size(), meshFacets); meshAdj.SetFacetNeighbourhood(); - this->_rclMesh.Adopt(meshPoints,meshFacets); + this->_rclMesh.Adopt(meshPoints, meshFacets); return true; } /** Loads an ASCII STL file. */ -bool MeshInput::LoadAsciiSTL (std::istream &rstrIn) +bool MeshInput::LoadAsciiSTL(std::istream& rstrIn) { boost::regex rx_p("^\\s*VERTEX\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" @@ -1127,11 +1207,12 @@ bool MeshInput::LoadAsciiSTL (std::istream &rstrIn) std::string line; float fX, fY, fZ; - unsigned long ulVertexCt, ulFacetCt=0; + unsigned long ulVertexCt, ulFacetCt = 0; MeshGeomFacet clFacet; - if (!rstrIn || rstrIn.bad()) + if (!rstrIn || rstrIn.bad()) { return false; + } std::streamoff ulSize = 0; std::streambuf* buf = rstrIn.rdbuf(); @@ -1142,13 +1223,16 @@ bool MeshInput::LoadAsciiSTL (std::istream &rstrIn) // count facets while (std::getline(rstrIn, line)) { boost::algorithm::to_upper(line); - if (line.find("ENDFACET") != std::string::npos) + if (line.find("ENDFACET") != std::string::npos) { ulFacetCt++; + } // prevent from reading EOF (as I don't know how to reread the file then) - if (rstrIn.tellg() > ulSize) + if (rstrIn.tellg() > ulSize) { break; - else if (line.find("ENDSOLID") != std::string::npos) + } + else if (line.find("ENDSOLID") != std::string::npos) { break; + } } // restart from the beginning @@ -1188,23 +1272,25 @@ bool MeshInput::LoadAsciiSTL (std::istream &rstrIn) } /** Loads a binary STL file. */ -bool MeshInput::LoadBinarySTL (std::istream &rstrIn) +bool MeshInput::LoadBinarySTL(std::istream& rstrIn) { char szInfo[80]; Base::Vector3f clVects[4]; uint16_t usAtt = 0; uint32_t ulCt = 0; - if (!rstrIn || rstrIn.bad()) + if (!rstrIn || rstrIn.bad()) { return false; + } // Header-Info ueberlesen rstrIn.read(szInfo, sizeof(szInfo)); // Anzahl Facets rstrIn.read((char*)&ulCt, sizeof(ulCt)); - if (rstrIn.bad()) + if (rstrIn.bad()) { return false; + } // get file size and calculate the number of facets std::streamoff ulSize = 0; @@ -1219,8 +1305,9 @@ bool MeshInput::LoadBinarySTL (std::istream &rstrIn) uint32_t ulFac = (ulSize - (80 + sizeof(uint32_t))) / 50; // compare the calculated with the read value - if (ulCt > ulFac) - return false;// not a valid STL file + if (ulCt > ulFac) { + return false; // not a valid STL file + } #if 0 MeshBuilder builder(this->_rclMesh); @@ -1246,18 +1333,18 @@ bool MeshInput::LoadBinarySTL (std::istream &rstrIn) } /** Loads the mesh object from an XML file. */ -void MeshInput::LoadXML (Base::XMLReader &reader) +void MeshInput::LoadXML(Base::XMLReader& reader) { MeshPointArray cPoints; MeshFacetArray cFacets; -// reader.readElement("Mesh"); + // reader.readElement("Mesh"); reader.readElement("Points"); int Cnt = reader.getAttributeAsInteger("Count"); cPoints.resize(Cnt); - for (int i=0 ;i mNode; - std::map mTria; - std::map mQuad; + std::map mNode; + std::map mTria; + std::map mQuad; int badElementCounter = 0; @@ -1380,8 +1474,9 @@ bool MeshInput::LoadNastran (std::istream &rstrIn) // Skip all the following tests } else if (line.rfind("GRID*", 0) == 0) { - // This element is the 16-digit-precision GRID element, which occupies two lines of the card. Note that - // FreeCAD discards the extra precision, downcasting to an four-byte float. + // This element is the 16-digit-precision GRID element, which occupies two lines of the + // card. Note that FreeCAD discards the extra precision, downcasting to an four-byte + // float. // // The two lines are: // 1 8 24 40 56 @@ -1389,32 +1484,33 @@ bool MeshInput::LoadNastran (std::istream &rstrIn) // * z(at least one) // // The first character is typically the sign, and may be omitted for positive numbers, - // so it is possible for a field to begin with a blank. Trailing zeros may be omitted, so - // a field may also end with blanks. No space or other delimiter is required between + // so it is possible for a field to begin with a blank. Trailing zeros may be omitted, + // so a field may also end with blanks. No space or other delimiter is required between // the numbers. The following is a valid NASTRAN GRID* element: // // GRID* 1 0.1234567890120. // * 1. // - if (line.length() < 8 + 16 + 16 + 16 + 1) { // Element type(8), index(16), empty(16), x(16), y(>=1) + if (line.length() + < 8 + 16 + 16 + 16 + 1) { // Element type(8), index(16), empty(16), x(16), y(>=1) badElementCounter++; continue; } auto indexView = std::string_view(&line[8], 16); - //auto blankView = std::string_view(&line[8+16], 16); // No data is needed here - auto xView = std::string_view(&line[8+16+16], 16); - auto yView = std::string_view(&line[8+16+16+16]); + // auto blankView = std::string_view(&line[8+16], 16); // No data is needed here + auto xView = std::string_view(&line[8 + 16 + 16], 16); + auto yView = std::string_view(&line[8 + 16 + 16 + 16]); std::string line2; std::getline(rstrIn, line2); - if ((!line2.empty() && line2[0] != '*') || - line2.length() < 9) { + if ((!line2.empty() && line2[0] != '*') || line2.length() < 9) { badElementCounter++; - continue; // File format error: second line is not a continuation line + continue; // File format error: second line is not a continuation line } auto zView = std::string_view(&line2[8]); - // We have to strip off any whitespace (technically really just any *trailing* whitespace): + // We have to strip off any whitespace (technically really just any *trailing* + // whitespace): auto indexString = boost::trim_copy(std::string(indexView)); auto xString = boost::trim_copy(std::string(xView)); auto yString = boost::trim_copy(std::string(yView)); @@ -1427,7 +1523,8 @@ bool MeshInput::LoadNastran (std::istream &rstrIn) badElementCounter++; continue; } - index = indexCheck.get() - 1; // Minus one so we are zero-indexed to match existing code + index = + indexCheck.get() - 1; // Minus one so we are zero-indexed to match existing code // Get the high-precision versions first auto x = boost::convert(xString, converter); @@ -1448,13 +1545,13 @@ bool MeshInput::LoadNastran (std::istream &rstrIn) else if (line.rfind("GRID", 0) == 0) { boost::regex rx_spaceDelimited("\\s*GRID\\s+([0-9]+)" - "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" - "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" - "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)\\s*"); + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)\\s*"); if (boost::regex_match(line.c_str(), what, rx_spaceDelimited)) { // insert the read-in vertex into a map to preserve the order - index = std::atol(what[1].first)-1; + index = std::atol(what[1].first) - 1; mNode[index].x = (float)std::atof(what[2].first); mNode[index].y = (float)std::atof(what[5].first); mNode[index].z = (float)std::atof(what[8].first); @@ -1466,7 +1563,8 @@ bool MeshInput::LoadNastran (std::istream &rstrIn) // GRID 1 1.2345671.2345671.234567 // GRID 112 6.0000000.5000000.00E+00 - if (line.length() < 41) { // Element type(8), id(8), cp(8), x(8), y(8), z(at least 1) + if (line.length() + < 41) { // Element type(8), id(8), cp(8), x(8), y(8), z(at least 1) badElementCounter++; continue; } @@ -1487,7 +1585,8 @@ bool MeshInput::LoadNastran (std::istream &rstrIn) badElementCounter++; continue; } - index = indexCheck.get() - 1; // Minus one so we are zero-indexed to match existing code + index = indexCheck.get() + - 1; // Minus one so we are zero-indexed to match existing code auto x = boost::convert(xString, converter); auto y = boost::convert(yString, converter); @@ -1507,20 +1606,20 @@ bool MeshInput::LoadNastran (std::istream &rstrIn) else if (line.rfind("CTRIA3 ", 0) == 0) { if (boost::regex_match(line.c_str(), what, rx_t)) { // insert the read-in triangle into a map to preserve the order - index = std::atol(what[1].first)-1; - mTria[index].iV[0] = std::atol(what[3].first)-1; - mTria[index].iV[1] = std::atol(what[4].first)-1; - mTria[index].iV[2] = std::atol(what[5].first)-1; + index = std::atol(what[1].first) - 1; + mTria[index].iV[0] = std::atol(what[3].first) - 1; + mTria[index].iV[1] = std::atol(what[4].first) - 1; + mTria[index].iV[2] = std::atol(what[5].first) - 1; } } else if (line.rfind("CQUAD4", 0) == 0) { if (boost::regex_match(line.c_str(), what, rx_q)) { // insert the read-in quadrangle into a map to preserve the order - index = std::atol(what[1].first)-1; - mQuad[index].iV[0] = std::atol(what[3].first)-1; - mQuad[index].iV[1] = std::atol(what[4].first)-1; - mQuad[index].iV[2] = std::atol(what[5].first)-1; - mQuad[index].iV[3] = std::atol(what[6].first)-1; + index = std::atol(what[1].first) - 1; + mQuad[index].iV[0] = std::atol(what[3].first) - 1; + mQuad[index].iV[1] = std::atol(what[4].first) - 1; + mQuad[index].iV[2] = std::atol(what[5].first) - 1; + mQuad[index].iV[3] = std::atol(what[6].first) - 1; } } } @@ -1533,7 +1632,8 @@ bool MeshInput::LoadNastran (std::istream &rstrIn) for (const auto& tri : mTria) { for (int i : tri.second.iV) { if (mNode.find(i) == mNode.end()) { - Base::Console().Error("CTRIA3 element refers to a node that does not exist, or could not be read.\n"); + Base::Console().Error( + "CTRIA3 element refers to a node that does not exist, or could not be read.\n"); return false; } } @@ -1543,41 +1643,44 @@ bool MeshInput::LoadNastran (std::istream &rstrIn) for (const auto& quad : mQuad) { for (int i : quad.second.iV) { if (mNode.find(i) == mNode.end()) { - Base::Console().Error("CQUAD4 element refers to a node that does not exist, or could not be read.\n"); + Base::Console().Error( + "CQUAD4 element refers to a node that does not exist, or could not be read.\n"); return false; } } } float fLength[2]; - if (mTria.empty()) + if (mTria.empty()) { index = 0; - else + } + else { index = mTria.rbegin()->first + 1; - for (const auto & QI : mQuad) { + } + for (const auto& QI : mQuad) { for (int i = 0; i < 2; i++) { - float fDx = mNode[QI.second.iV[i+2]].x - mNode[QI.second.iV[i]].x; - float fDy = mNode[QI.second.iV[i+2]].y - mNode[QI.second.iV[i]].y; - float fDz = mNode[QI.second.iV[i+2]].z - mNode[QI.second.iV[i]].z; - fLength[i] = fDx*fDx + fDy*fDy + fDz*fDz; + float fDx = mNode[QI.second.iV[i + 2]].x - mNode[QI.second.iV[i]].x; + float fDy = mNode[QI.second.iV[i + 2]].y - mNode[QI.second.iV[i]].y; + float fDz = mNode[QI.second.iV[i + 2]].z - mNode[QI.second.iV[i]].z; + fLength[i] = fDx * fDx + fDy * fDy + fDz * fDz; } if (fLength[0] < fLength[1]) { mTria[index].iV[0] = QI.second.iV[0]; mTria[index].iV[1] = QI.second.iV[1]; mTria[index].iV[2] = QI.second.iV[2]; - mTria[index+1].iV[0] = QI.second.iV[0]; - mTria[index+1].iV[1] = QI.second.iV[2]; - mTria[index+1].iV[2] = QI.second.iV[3]; + mTria[index + 1].iV[0] = QI.second.iV[0]; + mTria[index + 1].iV[1] = QI.second.iV[2]; + mTria[index + 1].iV[2] = QI.second.iV[3]; } else { mTria[index].iV[0] = QI.second.iV[0]; mTria[index].iV[1] = QI.second.iV[1]; mTria[index].iV[2] = QI.second.iV[3]; - mTria[index+1].iV[0] = QI.second.iV[1]; - mTria[index+1].iV[1] = QI.second.iV[2]; - mTria[index+1].iV[2] = QI.second.iV[3]; + mTria[index + 1].iV[0] = QI.second.iV[1]; + mTria[index + 1].iV[1] = QI.second.iV[2]; + mTria[index + 1].iV[2] = QI.second.iV[3]; } index += 2; @@ -1585,17 +1688,17 @@ bool MeshInput::LoadNastran (std::istream &rstrIn) // Applying the nodes vVertices.reserve(mNode.size()); - for (const auto & MI : mNode) { + for (const auto& MI : mNode) { vVertices.push_back(Base::Vector3f(MI.second.x, MI.second.y, MI.second.z)); } // Converting data to Mesh. Negative conversion for right orientation of normal-vectors. vTriangle.reserve(mTria.size()); - for (const auto & MI : mTria) { + for (const auto& MI : mTria) { clMeshFacet._aulPoints[0] = MI.second.iV[1]; clMeshFacet._aulPoints[1] = MI.second.iV[0]; clMeshFacet._aulPoints[2] = MI.second.iV[2]; - vTriangle.push_back (clMeshFacet); + vTriangle.push_back(clMeshFacet); } // make sure to add only vertices which are referenced by the triangles @@ -1605,10 +1708,11 @@ bool MeshInput::LoadNastran (std::istream &rstrIn) } /** Loads a Cadmould FE file. */ -bool MeshInput::LoadCadmouldFE (std::ifstream &rstrIn) +bool MeshInput::LoadCadmouldFE(std::ifstream& rstrIn) { - if (!rstrIn || rstrIn.bad()) + if (!rstrIn || rstrIn.bad()) { return false; + } assert(0); return false; } @@ -1644,8 +1748,9 @@ void MeshOutput::SetAsymptoteSize(const std::string& w, const std::string& h) void MeshOutput::Transform(const Base::Matrix4D& mat) { _transform = mat; - if (mat != Base::Matrix4D()) + if (mat != Base::Matrix4D()) { apply_transform = true; + } } std::vector MeshOutput::supportedMeshFormats() @@ -1742,8 +1847,9 @@ bool MeshOutput::SaveAny(const char* FileName, MeshIO::Format format) const // ask for write permission Base::FileInfo file(FileName); Base::FileInfo directory(file.dirPath()); - if ((file.exists() && !file.isWritable()) || !directory.exists() || !directory.isWritable()) - throw Base::FileException("No write permission for file",FileName); + if ((file.exists() && !file.isWritable()) || !directory.exists() || !directory.isWritable()) { + throw Base::FileException("No write permission for file", FileName); + } MeshIO::Format fileformat = format; if (fileformat == MeshIO::Undefined) { @@ -1761,10 +1867,10 @@ bool MeshOutput::SaveAny(const char* FileName, MeshIO::Format format) const // write file bool ok = false; - ok = aWriter.SaveBinarySTL( str ); - if (!ok) - throw Base::FileException("Export of STL mesh failed",FileName); - + ok = aWriter.SaveBinarySTL(str); + if (!ok) { + throw Base::FileException("Export of STL mesh failed", FileName); + } } else if (fileformat == MeshIO::ASTL) { MeshOutput aWriter(_rclMesh); @@ -1773,103 +1879,121 @@ bool MeshOutput::SaveAny(const char* FileName, MeshIO::Format format) const // write file bool ok = false; - ok = aWriter.SaveAsciiSTL( str ); - if (!ok) - throw Base::FileException("Export of STL mesh failed",FileName); + ok = aWriter.SaveAsciiSTL(str); + if (!ok) { + throw Base::FileException("Export of STL mesh failed", FileName); + } } else if (fileformat == MeshIO::OBJ) { // write file - if (!SaveOBJ(str, FileName)) - throw Base::FileException("Export of OBJ mesh failed",FileName); + if (!SaveOBJ(str, FileName)) { + throw Base::FileException("Export of OBJ mesh failed", FileName); + } } else if (fileformat == MeshIO::SMF) { // write file - if (!SaveSMF(str)) - throw Base::FileException("Export of SMF mesh failed",FileName); + if (!SaveSMF(str)) { + throw Base::FileException("Export of SMF mesh failed", FileName); + } } else if (fileformat == MeshIO::OFF) { // write file - if (!SaveOFF(str)) - throw Base::FileException("Export of OFF mesh failed",FileName); + if (!SaveOFF(str)) { + throw Base::FileException("Export of OFF mesh failed", FileName); + } } else if (fileformat == MeshIO::PLY) { // write file - if (!SaveBinaryPLY(str)) - throw Base::FileException("Export of PLY mesh failed",FileName); + if (!SaveBinaryPLY(str)) { + throw Base::FileException("Export of PLY mesh failed", FileName); + } } else if (fileformat == MeshIO::APLY) { // write file - if (!SaveAsciiPLY(str)) - throw Base::FileException("Export of PLY mesh failed",FileName); + if (!SaveAsciiPLY(str)) { + throw Base::FileException("Export of PLY mesh failed", FileName); + } } else if (fileformat == MeshIO::IDTF) { // write file - if (!SaveIDTF(str)) - throw Base::FileException("Export of IDTF mesh failed",FileName); + if (!SaveIDTF(str)) { + throw Base::FileException("Export of IDTF mesh failed", FileName); + } } else if (fileformat == MeshIO::MGL) { // write file - if (!SaveMGL(str)) - throw Base::FileException("Export of MGL mesh failed",FileName); + if (!SaveMGL(str)) { + throw Base::FileException("Export of MGL mesh failed", FileName); + } } else if (fileformat == MeshIO::IV) { // write file - if (!SaveInventor(str)) - throw Base::FileException("Export of Inventor mesh failed",FileName); + if (!SaveInventor(str)) { + throw Base::FileException("Export of Inventor mesh failed", FileName); + } } else if (fileformat == MeshIO::X3D) { // write file - if (!SaveX3D(str)) - throw Base::FileException("Export of X3D failed",FileName); + if (!SaveX3D(str)) { + throw Base::FileException("Export of X3D failed", FileName); + } } else if (fileformat == MeshIO::X3DZ) { // Compressed X3D is nothing else than a GZIP'ped X3D ascii file zipios::GZIPOutputStream gzip(str); // write file - if (!SaveX3D(gzip)) - throw Base::FileException("Export of compressed X3D mesh failed",FileName); + if (!SaveX3D(gzip)) { + throw Base::FileException("Export of compressed X3D mesh failed", FileName); + } } else if (fileformat == MeshIO::X3DOM) { // write file - if (!SaveX3DOM(str)) - throw Base::FileException("Export of X3DOM failed",FileName); + if (!SaveX3DOM(str)) { + throw Base::FileException("Export of X3DOM failed", FileName); + } } else if (fileformat == MeshIO::ThreeMF) { // write file - if (!Save3MF(str)) - throw Base::FileException("Export of 3MF failed",FileName); + if (!Save3MF(str)) { + throw Base::FileException("Export of 3MF failed", FileName); + } } else if (fileformat == MeshIO::PY) { // write file - if (!SavePython(str)) - throw Base::FileException("Export of Python mesh failed",FileName); + if (!SavePython(str)) { + throw Base::FileException("Export of Python mesh failed", FileName); + } } else if (fileformat == MeshIO::VRML) { // write file - if (!SaveVRML(str)) - throw Base::FileException("Export of VRML mesh failed",FileName); + if (!SaveVRML(str)) { + throw Base::FileException("Export of VRML mesh failed", FileName); + } } else if (fileformat == MeshIO::WRZ) { // Compressed VRML is nothing else than a GZIP'ped VRML ascii file // str.close(); - //Base::ogzstream gzip(FileName, std::ios::out | std::ios::binary); - //Hint: The compression level seems to be higher than with ogzstream - //which leads to problems to load the wrz file in debug mode, the - //application simply crashes. + // Base::ogzstream gzip(FileName, std::ios::out | std::ios::binary); + // Hint: The compression level seems to be higher than with ogzstream + // which leads to problems to load the wrz file in debug mode, the + // application simply crashes. zipios::GZIPOutputStream gzip(str); // write file - if (!SaveVRML(gzip)) - throw Base::FileException("Export of compressed VRML mesh failed",FileName); + if (!SaveVRML(gzip)) { + throw Base::FileException("Export of compressed VRML mesh failed", FileName); + } } else if (fileformat == MeshIO::NAS) { // write file - if (!SaveNastran(str)) - throw Base::FileException("Export of NASTRAN mesh failed",FileName); + if (!SaveNastran(str)) { + throw Base::FileException("Export of NASTRAN mesh failed", FileName); + } } else if (fileformat == MeshIO::ASY) { // write file - if (!SaveAsymptote(str)) - throw Base::FileException("Export of ASY mesh failed",FileName); + if (!SaveAsymptote(str)) { + throw Base::FileException("Export of ASY mesh failed", FileName); + } } else { throw Base::FileException("File format not supported", FileName); @@ -1878,72 +2002,75 @@ bool MeshOutput::SaveAny(const char* FileName, MeshIO::Format format) const return true; } -bool MeshOutput::SaveFormat(std::ostream &str, MeshIO::Format fmt) const +bool MeshOutput::SaveFormat(std::ostream& str, MeshIO::Format fmt) const { switch (fmt) { - case MeshIO::BMS: - _rclMesh.Write(str); - return true; - case MeshIO::ASTL: - return SaveAsciiSTL(str); - case MeshIO::BSTL: - return SaveBinarySTL(str); - case MeshIO::OBJ: - return SaveOBJ(str); - case MeshIO::SMF: - return SaveSMF(str); - case MeshIO::OFF: - return SaveOFF(str); - case MeshIO::IDTF: - return SaveIDTF(str); - case MeshIO::MGL: - return SaveMGL(str); - case MeshIO::IV: - return SaveInventor(str); - case MeshIO::X3D: - return SaveX3D(str); - case MeshIO::X3DOM: - return SaveX3DOM(str); - case MeshIO::VRML: - return SaveVRML(str); - case MeshIO::WRZ: - // it's up to the client to create the needed stream - return SaveVRML(str); - case MeshIO::ThreeMF: - return Save3MF(str); - case MeshIO::NAS: - return SaveNastran(str); - case MeshIO::PLY: - return SaveBinaryPLY(str); - case MeshIO::APLY: - return SaveAsciiPLY(str); - case MeshIO::PY: - return SavePython(str); - case MeshIO::ASY: - return SaveAsymptote(str); - default: - throw Base::FileException("Unsupported file format"); + case MeshIO::BMS: + _rclMesh.Write(str); + return true; + case MeshIO::ASTL: + return SaveAsciiSTL(str); + case MeshIO::BSTL: + return SaveBinarySTL(str); + case MeshIO::OBJ: + return SaveOBJ(str); + case MeshIO::SMF: + return SaveSMF(str); + case MeshIO::OFF: + return SaveOFF(str); + case MeshIO::IDTF: + return SaveIDTF(str); + case MeshIO::MGL: + return SaveMGL(str); + case MeshIO::IV: + return SaveInventor(str); + case MeshIO::X3D: + return SaveX3D(str); + case MeshIO::X3DOM: + return SaveX3DOM(str); + case MeshIO::VRML: + return SaveVRML(str); + case MeshIO::WRZ: + // it's up to the client to create the needed stream + return SaveVRML(str); + case MeshIO::ThreeMF: + return Save3MF(str); + case MeshIO::NAS: + return SaveNastran(str); + case MeshIO::PLY: + return SaveBinaryPLY(str); + case MeshIO::APLY: + return SaveAsciiPLY(str); + case MeshIO::PY: + return SavePython(str); + case MeshIO::ASY: + return SaveAsymptote(str); + default: + throw Base::FileException("Unsupported file format"); } } /** Saves the mesh object into an ASCII file. */ -bool MeshOutput::SaveAsciiSTL (std::ostream &rstrOut) const +bool MeshOutput::SaveAsciiSTL(std::ostream& rstrOut) const { MeshFacetIterator clIter(_rclMesh), clEnd(_rclMesh); clIter.Transform(this->_transform); - const MeshGeomFacet *pclFacet; + const MeshGeomFacet* pclFacet; - if (!rstrOut || rstrOut.bad() || _rclMesh.CountFacets() == 0) + if (!rstrOut || rstrOut.bad() || _rclMesh.CountFacets() == 0) { return false; + } rstrOut.precision(6); rstrOut.setf(std::ios::fixed | std::ios::showpoint); Base::SequencerLauncher seq("saving...", _rclMesh.CountFacets() + 1); - if (this->objectName.empty()) + if (this->objectName.empty()) { rstrOut << "solid Mesh\n"; - else + } + else { rstrOut << "solid " << this->objectName << '\n'; + } clIter.Begin(); clEnd.End(); @@ -1951,23 +2078,20 @@ bool MeshOutput::SaveAsciiSTL (std::ostream &rstrOut) const pclFacet = &(*clIter); // normal - rstrOut << " facet normal " << pclFacet->GetNormal().x << " " - << pclFacet->GetNormal().y << " " - << pclFacet->GetNormal().z << '\n'; + rstrOut << " facet normal " << pclFacet->GetNormal().x << " " << pclFacet->GetNormal().y + << " " << pclFacet->GetNormal().z << '\n'; rstrOut << " outer loop\n"; // vertices for (const auto& pnt : pclFacet->_aclPoints) { - rstrOut << " vertex " << pnt.x << " " - << pnt.y << " " - << pnt.z << '\n'; + rstrOut << " vertex " << pnt.x << " " << pnt.y << " " << pnt.z << '\n'; } rstrOut << " endloop\n"; rstrOut << " endfacet\n"; ++clIter; - seq.next(true);// allow to cancel + seq.next(true); // allow to cancel } rstrOut << "endsolid Mesh\n"; @@ -1976,17 +2100,18 @@ bool MeshOutput::SaveAsciiSTL (std::ostream &rstrOut) const } /** Saves the mesh object into a binary file. */ -bool MeshOutput::SaveBinarySTL (std::ostream &rstrOut) const +bool MeshOutput::SaveBinarySTL(std::ostream& rstrOut) const { MeshFacetIterator clIter(_rclMesh), clEnd(_rclMesh); clIter.Transform(this->_transform); - const MeshGeomFacet *pclFacet; + const MeshGeomFacet* pclFacet; uint32_t i; uint16_t usAtt; char szInfo[81]; - if (!rstrOut || rstrOut.bad() /*|| _rclMesh.CountFacets() == 0*/) + if (!rstrOut || rstrOut.bad() /*|| _rclMesh.CountFacets() == 0*/) { return false; + } Base::SequencerLauncher seq("saving...", _rclMesh.CountFacets() + 1); @@ -2019,14 +2144,14 @@ bool MeshOutput::SaveBinarySTL (std::ostream &rstrOut) const rstrOut.write((const char*)&usAtt, sizeof(usAtt)); ++clIter; - seq.next(true); // allow to cancel + seq.next(true); // allow to cancel } return true; } /** Saves an OBJ file. */ -bool MeshOutput::SaveOBJ (std::ostream &out) const +bool MeshOutput::SaveOBJ(std::ostream& out) const { WriterOBJ writer(this->_rclMesh, this->_material); writer.SetTransform(this->_transform); @@ -2034,7 +2159,7 @@ bool MeshOutput::SaveOBJ (std::ostream &out) const return writer.Save(out); } -bool MeshOutput::SaveOBJ (std::ostream &out, const char* filename) const +bool MeshOutput::SaveOBJ(std::ostream& out, const char* filename) const { WriterOBJ writer(this->_rclMesh, this->_material); writer.SetTransform(this->_transform); @@ -2056,14 +2181,15 @@ bool MeshOutput::SaveOBJ (std::ostream &out, const char* filename) const } /** Saves an SMF file. */ -bool MeshOutput::SaveSMF (std::ostream &out) const +bool MeshOutput::SaveSMF(std::ostream& out) const { // http://people.sc.fsu.edu/~jburkardt/data/smf/smf.txt const MeshPointArray& rPoints = _rclMesh.GetPoints(); const MeshFacetArray& rFacets = _rclMesh.GetFacets(); - if (!out || out.bad()) + if (!out || out.bad()) { return false; + } Base::SequencerLauncher seq("saving...", _rclMesh.CountPoints() + _rclMesh.CountFacets()); @@ -2089,22 +2215,21 @@ bool MeshOutput::SaveSMF (std::ostream &out) const } out << "v " << pt.x << " " << pt.y << " " << pt.z << '\n'; - seq.next(true); // allow to cancel + seq.next(true); // allow to cancel } // facet indices - for (const auto & it : rFacets) { - out << "f " << it._aulPoints[0]+1 << " " - << it._aulPoints[1]+1 << " " - << it._aulPoints[2]+1 << '\n'; - seq.next(true); // allow to cancel + for (const auto& it : rFacets) { + out << "f " << it._aulPoints[0] + 1 << " " << it._aulPoints[1] + 1 << " " + << it._aulPoints[2] + 1 << '\n'; + seq.next(true); // allow to cancel } return true; } /** Saves an Asymptote file. */ -bool MeshOutput::SaveAsymptote(std::ostream &out) const +bool MeshOutput::SaveAsymptote(std::ostream& out) const { out << "/*\n" " * Created by FreeCAD \n" @@ -2114,8 +2239,9 @@ bool MeshOutput::SaveAsymptote(std::ostream &out) const if (!asyWidth.empty()) { out << "size(" << asyWidth; - if (!asyHeight.empty()) + if (!asyHeight.empty()) { out << ", " << asyHeight; + } out << ");\n\n"; } @@ -2128,23 +2254,21 @@ bool MeshOutput::SaveAsymptote(std::ostream &out) const Base::Vector3f upvec(0.0f, 0.0f, 1.0f); out << "// CA:Camera, OB:Camera\n" - << "currentprojection = orthographic(camera = (" << camera.x << ", " - << camera.y << ", " - << camera.z << "),\n" - << " target = (" << target.x << ", " - << target.y << ", " - << target.z << "),\n" + << "currentprojection = orthographic(camera = (" << camera.x << ", " << camera.y << ", " + << camera.z << "),\n" + << " target = (" << target.x << ", " << target.y << ", " + << target.z + << "),\n" " showtarget = false,\n" - " up = (" << upvec.x << ", " - << upvec.y << ", " - << upvec.z << "));\n\n"; + " up = (" + << upvec.x << ", " << upvec.y << ", " << upvec.z << "));\n\n"; - //out << "// LA:Spot, OB:Lamp\n" - // << "// WO:World\n" - // << "currentlight = light(diffuse = rgb(1, 1, 1),\n" - // " specular = rgb(1, 1, 1),\n" - // " background = rgb(0.078281, 0.16041, 0.25),\n" - // " 0.56639, 0.21839, 0.79467);\n\n"; + // out << "// LA:Spot, OB:Lamp\n" + // << "// WO:World\n" + // << "currentlight = light(diffuse = rgb(1, 1, 1),\n" + // " specular = rgb(1, 1, 1),\n" + // " background = rgb(0.078281, 0.16041, 0.25),\n" + // " 0.56639, 0.21839, 0.79467);\n\n"; out << "// ME:Mesh, OB:Mesh\n"; @@ -2155,19 +2279,18 @@ bool MeshOutput::SaveAsymptote(std::ostream &out) const const MeshPointArray& rPoints = _rclMesh.GetPoints(); const MeshFacetArray& rFacets = _rclMesh.GetFacets(); - bool saveVertexColor = (_material && _material->binding == MeshIO::PER_VERTEX && - _material->diffuseColor.size() == rPoints.size()); - bool saveFaceColor = (_material && _material->binding == MeshIO::PER_FACE && - _material->diffuseColor.size() == rFacets.size()); + bool saveVertexColor = (_material && _material->binding == MeshIO::PER_VERTEX + && _material->diffuseColor.size() == rPoints.size()); + bool saveFaceColor = (_material && _material->binding == MeshIO::PER_FACE + && _material->diffuseColor.size() == rFacets.size()); // global mesh color App::Color mc(0.8f, 0.8f, 0.8f); - if (_material && _material->binding == MeshIO::OVERALL && - _material->diffuseColor.size() == 1) { + if (_material && _material->binding == MeshIO::OVERALL && _material->diffuseColor.size() == 1) { mc = _material->diffuseColor[0]; } std::size_t index = 0; - const MeshGeomFacet *pclFacet; + const MeshGeomFacet* pclFacet; while (clIter < clEnd) { pclFacet = &(*clIter); @@ -2175,9 +2298,7 @@ bool MeshOutput::SaveAsymptote(std::ostream &out) const // vertices for (const auto& pnt : pclFacet->_aclPoints) { - out << '(' << pnt.x << ", " - << pnt.y << ", " - << pnt.z << ")--"; + out << '(' << pnt.x << ", " << pnt.y << ", " << pnt.z << ")--"; } out << "cycle"; @@ -2188,8 +2309,9 @@ bool MeshOutput::SaveAsymptote(std::ostream &out) const for (int i = 0; i < 3; i++) { const App::Color& c = _material->diffuseColor[face._aulPoints[i]]; out << "rgb(" << c.r << ", " << c.g << ", " << c.b << ")"; - if (i < 2) + if (i < 2) { out << ", "; + } } out << "}));\n"; } @@ -2209,24 +2331,27 @@ bool MeshOutput::SaveAsymptote(std::ostream &out) const } /** Saves an OFF file. */ -bool MeshOutput::SaveOFF (std::ostream &out) const +bool MeshOutput::SaveOFF(std::ostream& out) const { const MeshPointArray& rPoints = _rclMesh.GetPoints(); const MeshFacetArray& rFacets = _rclMesh.GetFacets(); - if (!out || out.bad()) + if (!out || out.bad()) { return false; + } Base::SequencerLauncher seq("saving...", _rclMesh.CountPoints() + _rclMesh.CountFacets()); bool exportColor = false; if (_material) { if (_material->binding == MeshIO::PER_FACE) { - Base::Console().Warning("Cannot export color information because it's defined per face"); + Base::Console().Warning( + "Cannot export color information because it's defined per face"); } else if (_material->binding == MeshIO::PER_VERTEX) { if (_material->diffuseColor.size() != rPoints.size()) { - Base::Console().Warning("Cannot export color information because there is a different number of points and colors"); + Base::Console().Warning("Cannot export color information because there is a " + "different number of points and colors"); } else { exportColor = true; @@ -2234,7 +2359,8 @@ bool MeshOutput::SaveOFF (std::ostream &out) const } else if (_material->binding == MeshIO::OVERALL) { if (_material->diffuseColor.empty()) { - Base::Console().Warning("Cannot export color information because there is no color defined"); + Base::Console().Warning( + "Cannot export color information because there is no color defined"); } else { exportColor = true; @@ -2242,10 +2368,12 @@ bool MeshOutput::SaveOFF (std::ostream &out) const } } - if (exportColor) + if (exportColor) { out << "COFF\n"; - else + } + else { out << "OFF\n"; + } out << rPoints.size() << " " << rFacets.size() << " 0\n"; // vertices @@ -2273,35 +2401,36 @@ bool MeshOutput::SaveOFF (std::ostream &out) const int b = static_cast(c.b * 255.0f); int a = static_cast(c.a * 255.0f); - out << pt.x << " " << pt.y << " " << pt.z << " " << r << " " << g << " " << b << " " << a << '\n'; + out << pt.x << " " << pt.y << " " << pt.z << " " << r << " " << g << " " << b << " " + << a << '\n'; } else { out << pt.x << " " << pt.y << " " << pt.z << '\n'; } - seq.next(true); // allow to cancel + seq.next(true); // allow to cancel } // facet indices (no texture and normal indices) - for (const auto & it : rFacets) { - out << "3 " << it._aulPoints[0] - << " " << it._aulPoints[1] - << " " << it._aulPoints[2] << '\n'; - seq.next(true); // allow to cancel + for (const auto& it : rFacets) { + out << "3 " << it._aulPoints[0] << " " << it._aulPoints[1] << " " << it._aulPoints[2] + << '\n'; + seq.next(true); // allow to cancel } return true; } -bool MeshOutput::SaveBinaryPLY (std::ostream &out) const +bool MeshOutput::SaveBinaryPLY(std::ostream& out) const { const MeshPointArray& rPoints = _rclMesh.GetPoints(); const MeshFacetArray& rFacets = _rclMesh.GetFacets(); std::size_t v_count = rPoints.size(); std::size_t f_count = rFacets.size(); - if (!out || out.bad()) + if (!out || out.bad()) { return false; + } bool saveVertexColor = (_material && _material->binding == MeshIO::PER_VERTEX - && _material->diffuseColor.size() == rPoints.size()); + && _material->diffuseColor.size() == rPoints.size()); out << "ply\n" << "format binary_little_endian 1.0\n" << "comment Created by FreeCAD \n" @@ -2352,17 +2481,18 @@ bool MeshOutput::SaveBinaryPLY (std::ostream &out) const return true; } -bool MeshOutput::SaveAsciiPLY (std::ostream &out) const +bool MeshOutput::SaveAsciiPLY(std::ostream& out) const { const MeshPointArray& rPoints = _rclMesh.GetPoints(); const MeshFacetArray& rFacets = _rclMesh.GetFacets(); std::size_t v_count = rPoints.size(); std::size_t f_count = rFacets.size(); - if (!out || out.bad()) + if (!out || out.bad()) { return false; + } bool saveVertexColor = (_material && _material->binding == MeshIO::PER_VERTEX - && _material->diffuseColor.size() == rPoints.size()); + && _material->diffuseColor.size() == rPoints.size()); out << "ply\n" << "format ascii 1.0\n" << "comment Created by FreeCAD \n" @@ -2425,33 +2555,33 @@ bool MeshOutput::SaveAsciiPLY (std::ostream &out) const return true; } -bool MeshOutput::SaveMeshNode (std::ostream &rstrOut) +bool MeshOutput::SaveMeshNode(std::ostream& rstrOut) { const MeshPointArray& rPoints = _rclMesh.GetPoints(); const MeshFacetArray& rFacets = _rclMesh.GetFacets(); - if (!rstrOut || rstrOut.bad()) + if (!rstrOut || rstrOut.bad()) { return false; + } // vertices rstrOut << "[" << '\n'; if (this->apply_transform) { Base::Vector3f pt; - for (const auto & it : rPoints) { + for (const auto& it : rPoints) { pt = this->_transform * it; rstrOut << "v " << pt.x << " " << pt.y << " " << pt.z << '\n'; } } else { - for (const auto & it : rPoints) { + for (const auto& it : rPoints) { rstrOut << "v " << it.x << " " << it.y << " " << it.z << '\n'; } } // facet indices (no texture and normal indices) - for (const auto & it : rFacets) { - rstrOut << "f " << it._aulPoints[0]+1 << " " - << it._aulPoints[1]+1 << " " - << it._aulPoints[2]+1 << '\n'; + for (const auto& it : rFacets) { + rstrOut << "f " << it._aulPoints[0] + 1 << " " << it._aulPoints[1] + 1 << " " + << it._aulPoints[2] + 1 << '\n'; } rstrOut << "]" << '\n'; @@ -2459,7 +2589,7 @@ bool MeshOutput::SaveMeshNode (std::ostream &rstrOut) } /** Saves the mesh object into an XML file. */ -void MeshOutput::SaveXML (Base::Writer &writer) const +void MeshOutput::SaveXML(Base::Writer& writer) const { const MeshPointArray& rPoints = _rclMesh.GetPoints(); const MeshFacetArray& rFacets = _rclMesh.GetFacets(); @@ -2467,27 +2597,26 @@ void MeshOutput::SaveXML (Base::Writer &writer) const // writer << writer.ind() << "" << '\n'; writer.incInd(); - writer.Stream() << writer.ind() << "" << '\n'; + writer.Stream() << writer.ind() << "" + << '\n'; writer.incInd(); if (this->apply_transform) { Base::Vector3f pt; - for (const auto & it : rPoints) { + for (const auto& it : rPoints) { pt = this->_transform * it; - writer.Stream() << writer.ind() << "

" - << '\n'; + writer.Stream() << writer.ind() << "

" << '\n'; } } else { - for (const auto & it : rPoints) { - writer.Stream() << writer.ind() << "

" - << '\n'; + for (const auto& it : rPoints) { + writer.Stream() << writer.ind() << "

" << '\n'; } } writer.decInd(); @@ -2497,15 +2626,14 @@ void MeshOutput::SaveXML (Base::Writer &writer) const writer.Stream() << writer.ind() << "" << '\n'; writer.incInd(); - for (const auto & it : rFacets) { + for (const auto& it : rFacets) { writer.Stream() << writer.ind() << "" - << '\n'; + << "p0=\"" << it._aulPoints[0] << "\" " + << "p1=\"" << it._aulPoints[1] << "\" " + << "p2=\"" << it._aulPoints[2] << "\" " + << "n0=\"" << it._aulNeighbours[0] << "\" " + << "n1=\"" << it._aulNeighbours[1] << "\" " + << "n2=\"" << it._aulNeighbours[2] << "\"/>" << '\n'; } writer.decInd(); writer.Stream() << writer.ind() << "" << '\n'; @@ -2515,7 +2643,7 @@ void MeshOutput::SaveXML (Base::Writer &writer) const } /** Saves the mesh object into a 3MF file. */ -bool MeshOutput::Save3MF(std::ostream &str) const +bool MeshOutput::Save3MF(std::ostream& str) const { Writer3MF writer(str); writer.AddMesh(_rclMesh, _transform); @@ -2523,16 +2651,18 @@ bool MeshOutput::Save3MF(std::ostream &str) const } /** Writes an IDTF file. */ -bool MeshOutput::SaveIDTF (std::ostream &str) const +bool MeshOutput::SaveIDTF(std::ostream& str) const { - if (!str || str.bad() || (_rclMesh.CountFacets() == 0)) + if (!str || str.bad() || (_rclMesh.CountFacets() == 0)) { return false; + } const MeshPointArray& pts = _rclMesh.GetPoints(); const MeshFacetArray& fts = _rclMesh.GetFacets(); std::string resource = objectName; - if (resource.empty()) + if (resource.empty()) { resource = "Resource"; + } str.precision(6); str.setf(std::ios::fixed | std::ios::showpoint); @@ -2565,7 +2695,7 @@ bool MeshOutput::SaveIDTF (std::ostream &str) const str << Base::tabs(2) << "MESH {\n"; str << Base::tabs(3) << "FACE_COUNT " << fts.size() << '\n'; str << Base::tabs(3) << "MODEL_POSITION_COUNT " << pts.size() << '\n'; - str << Base::tabs(3) << "MODEL_NORMAL_COUNT " << 3*fts.size() << '\n'; + str << Base::tabs(3) << "MODEL_NORMAL_COUNT " << 3 * fts.size() << '\n'; str << Base::tabs(3) << "MODEL_DIFFUSE_COLOR_COUNT 0\n"; str << Base::tabs(3) << "MODEL_SPECULAR_COLOR_COUNT 0\n"; str << Base::tabs(3) << "MODEL_TEXTURE_COORD_COUNT 0\n"; @@ -2578,8 +2708,9 @@ bool MeshOutput::SaveIDTF (std::ostream &str) const str << Base::tabs(4) << "}\n"; str << Base::tabs(3) << "}\n"; str << Base::tabs(3) << "MESH_FACE_POSITION_LIST {\n"; - for (const auto & ft : fts) { - str << Base::tabs(4) << ft._aulPoints[0] << " " << ft._aulPoints[1] << " " << ft._aulPoints[2] << '\n'; + for (const auto& ft : fts) { + str << Base::tabs(4) << ft._aulPoints[0] << " " << ft._aulPoints[1] << " " + << ft._aulPoints[2] << '\n'; } str << Base::tabs(3) << "}\n"; str << Base::tabs(3) << "MESH_FACE_NORMAL_LIST {\n"; @@ -2595,12 +2726,12 @@ bool MeshOutput::SaveIDTF (std::ostream &str) const } str << Base::tabs(3) << "}\n"; str << Base::tabs(3) << "MODEL_POSITION_LIST {\n"; - for (const auto & pt : pts) { + for (const auto& pt : pts) { str << Base::tabs(4) << pt.x << " " << pt.y << " " << pt.z << '\n'; } str << Base::tabs(3) << "}\n"; str << Base::tabs(3) << "MODEL_NORMAL_LIST {\n"; - for (const auto & ft : fts) { + for (const auto& ft : fts) { MeshGeomFacet face = _rclMesh.GetFacet(ft); Base::Vector3f normal = face.GetNormal(); str << Base::tabs(4) << normal.x << " " << normal.y << " " << normal.z << '\n'; @@ -2617,19 +2748,20 @@ bool MeshOutput::SaveIDTF (std::ostream &str) const } /** Writes an MGL file. */ -bool MeshOutput::SaveMGL (std::ostream &str) const +bool MeshOutput::SaveMGL(std::ostream& str) const { -/* -light on -list t 0 1 2 | 0 1 3 | 0 2 3 | 1 2 3 -list xt 1 1 0 0 -list yt -1 -1 1 0 -list zt -1 -1 -1 1 -triplot t xt yt zt 'b' -#triplot t xt yt zt '#k' -*/ - if (!str || str.bad() || (_rclMesh.CountFacets() == 0)) + /* + light on + list t 0 1 2 | 0 1 3 | 0 2 3 | 1 2 3 + list xt 1 1 0 0 + list yt -1 -1 1 0 + list zt -1 -1 -1 1 + triplot t xt yt zt 'b' + #triplot t xt yt zt '#k' + */ + if (!str || str.bad() || (_rclMesh.CountFacets() == 0)) { return false; + } const MeshPointArray& pts = _rclMesh.GetPoints(); const MeshFacetArray& fts = _rclMesh.GetFacets(); @@ -2639,25 +2771,25 @@ triplot t xt yt zt 'b' str << "light on\n"; str << "list t "; - for (const auto & ft : fts) { + for (const auto& ft : fts) { str << ft._aulPoints[0] << " " << ft._aulPoints[1] << " " << ft._aulPoints[2] << " | "; } str << std::endl; str << "list xt "; - for (const auto & pt : pts) { + for (const auto& pt : pts) { str << pt.x << " "; } str << std::endl; str << "list yt "; - for (const auto & pt : pts) { + for (const auto& pt : pts) { str << pt.y << " "; } str << std::endl; str << "list zt "; - for (const auto & pt : pts) { + for (const auto& pt : pts) { str << pt.z << " "; } str << std::endl; @@ -2669,7 +2801,7 @@ triplot t xt yt zt 'b' } /** Writes an OpenInventor file. */ -bool MeshOutput::SaveInventor (std::ostream &rstrOut) const +bool MeshOutput::SaveInventor(std::ostream& rstrOut) const { WriterInventor writer(_rclMesh, _material); writer.SetTransform(_transform); @@ -2677,10 +2809,11 @@ bool MeshOutput::SaveInventor (std::ostream &rstrOut) const } /** Writes an X3D file. */ -bool MeshOutput::SaveX3D (std::ostream &out) const +bool MeshOutput::SaveX3D(std::ostream& out) const { - if (!out || out.bad() || (_rclMesh.CountFacets() == 0)) + if (!out || out.bad() || (_rclMesh.CountFacets() == 0)) { return false; + } // XML header info out << "\n"; @@ -2689,26 +2822,29 @@ bool MeshOutput::SaveX3D (std::ostream &out) const } /** Writes an X3D file. */ -bool MeshOutput::SaveX3DContent (std::ostream &out, bool exportViewpoints) const +bool MeshOutput::SaveX3DContent(std::ostream& out, bool exportViewpoints) const { - if (!out || out.bad() || (_rclMesh.CountFacets() == 0)) + if (!out || out.bad() || (_rclMesh.CountFacets() == 0)) { return false; + } const MeshPointArray& pts = _rclMesh.GetPoints(); const MeshFacetArray& fts = _rclMesh.GetFacets(); Base::BoundBox3f bbox = _rclMesh.GetBoundBox(); - if (apply_transform) + if (apply_transform) { bbox = bbox.Transformed(_transform); + } App::Color mat(0.65f, 0.65f, 0.65f); if (_material && _material->binding == MeshIO::Binding::OVERALL) { - if (!_material->diffuseColor.empty()) + if (!_material->diffuseColor.empty()) { mat = _material->diffuseColor.front(); + } } - bool saveVertexColor = (_material && _material->binding == MeshIO::PER_VERTEX && - _material->diffuseColor.size() == pts.size()); - bool saveFaceColor = (_material && _material->binding == MeshIO::PER_FACE && - _material->diffuseColor.size() == fts.size()); + bool saveVertexColor = (_material && _material->binding == MeshIO::PER_VERTEX + && _material->diffuseColor.size() == pts.size()); + bool saveFaceColor = (_material && _material->binding == MeshIO::PER_FACE + && _material->diffuseColor.size() == fts.size()); Base::SequencerLauncher seq("Saving...", _rclMesh.CountFacets() + 1); out.precision(6); @@ -2717,7 +2853,8 @@ bool MeshOutput::SaveX3DContent (std::ostream &out, bool exportViewpoints) const // Header info out << R"(\n"; + << "\"http://www.web3d.org/specifications/x3d-3.2.xsd\" width=\"1280px\" " + "height=\"1024px\">\n"; out << " \n" << " \n" << " \n" @@ -2728,52 +2865,78 @@ bool MeshOutput::SaveX3DContent (std::ostream &out, bool exportViewpoints) const out << " \n"; if (exportViewpoints) { - auto viewpoint = [&out](const char* text, const Base::Vector3f& cnt, - const Base::Vector3f& pos, const Base::Vector3f& axis, float angle) { - out << " )" + auto viewpoint = [&out](const char* text, + const Base::Vector3f& cnt, + const Base::Vector3f& pos, + const Base::Vector3f& axis, + float angle) { + out << " )" << "\n"; }; Base::Vector3f cnt = bbox.GetCenter(); float dist = 1.2f * bbox.CalcDiagonalLength(); - float dist3 = 0.577350f * dist; // sqrt(1/3) * dist + float dist3 = 0.577350f * dist; // sqrt(1/3) * dist - viewpoint("Iso", cnt, Base::Vector3f(cnt.x + dist3, cnt.y - dist3, cnt.z + dist3), Base::Vector3f(0.742906f, 0.307722f, 0.594473f), 1.21712f); - viewpoint("Front", cnt, Base::Vector3f(cnt.x, cnt.y - dist, cnt.z), Base::Vector3f(1.0f, 0.0f, 0.0f), 1.5707964f); - viewpoint("Back", cnt, Base::Vector3f(cnt.x, cnt.y + dist, cnt.z), Base::Vector3f(0.0f, 0.707106f, 0.707106f), 3.141592f); - viewpoint("Right", cnt, Base::Vector3f(cnt.x + dist, cnt.y, cnt.z), Base::Vector3f(0.577350f, 0.577350f, 0.577350f), 2.094395f); - viewpoint("Left", cnt, Base::Vector3f(cnt.x - dist, cnt.y, cnt.z), Base::Vector3f(-0.577350f, 0.577350f, 0.577350f), 4.188790f); - viewpoint("Top", cnt, Base::Vector3f(cnt.x, cnt.y, cnt.z + dist), Base::Vector3f(0.0f, 0.0f, 1.0f), 0.0f); - viewpoint("Bottom", cnt, Base::Vector3f(cnt.x, cnt.y, cnt.z - dist), Base::Vector3f(1.0f, 0.0f, 0.0f), 3.141592f); + viewpoint("Iso", + cnt, + Base::Vector3f(cnt.x + dist3, cnt.y - dist3, cnt.z + dist3), + Base::Vector3f(0.742906f, 0.307722f, 0.594473f), + 1.21712f); + viewpoint("Front", + cnt, + Base::Vector3f(cnt.x, cnt.y - dist, cnt.z), + Base::Vector3f(1.0f, 0.0f, 0.0f), + 1.5707964f); + viewpoint("Back", + cnt, + Base::Vector3f(cnt.x, cnt.y + dist, cnt.z), + Base::Vector3f(0.0f, 0.707106f, 0.707106f), + 3.141592f); + viewpoint("Right", + cnt, + Base::Vector3f(cnt.x + dist, cnt.y, cnt.z), + Base::Vector3f(0.577350f, 0.577350f, 0.577350f), + 2.094395f); + viewpoint("Left", + cnt, + Base::Vector3f(cnt.x - dist, cnt.y, cnt.z), + Base::Vector3f(-0.577350f, 0.577350f, 0.577350f), + 4.188790f); + viewpoint("Top", + cnt, + Base::Vector3f(cnt.x, cnt.y, cnt.z + dist), + Base::Vector3f(0.0f, 0.0f, 1.0f), + 0.0f); + viewpoint("Bottom", + cnt, + Base::Vector3f(cnt.x, cnt.y, cnt.z - dist), + Base::Vector3f(1.0f, 0.0f, 0.0f), + 3.141592f); } if (apply_transform) { Base::Placement p(_transform); const Base::Vector3d& v = p.getPosition(); const Base::Rotation& r = p.getRotation(); - Base::Vector3d axis; double angle; + Base::Vector3d axis; + double angle; r.getValue(axis, angle); out << " \n"; + << "translation='" << v.x << " " << v.y << " " << v.z << "' " + << "rotation='" << axis.x << " " << axis.y << " " << axis.z << " " << angle << "'>\n"; } else { out << " \n"; } out << " \n"; out << " \n" - " \n" + " \n" " \n"; out << " \n"; out << " \n"; @@ -2818,24 +2981,29 @@ bool MeshOutput::SaveX3DContent (std::ostream &out, bool exportViewpoints) const } /** Writes an X3DOM file. */ -bool MeshOutput::SaveX3DOM (std::ostream &out) const +bool MeshOutput::SaveX3DOM(std::ostream& out) const { - if (!out || out.bad() || (_rclMesh.CountFacets() == 0)) + if (!out || out.bad() || (_rclMesh.CountFacets() == 0)) { return false; + } // See: // https://stackoverflow.com/questions/31976056/unable-to-color-faces-using-indexedfaceset-in-x3dom // out << "\n" - << "\n"; + << "\n"; out << "\n" << " \n" - << " \n" - << " \n" + << " \n" + << " \n" << " \n"; auto onclick = [&out](const char* text) { - out << " \n"; + out << " \n"; }; onclick("Iso"); @@ -2846,7 +3014,7 @@ bool MeshOutput::SaveX3DOM (std::ostream &out) const onclick("Top"); onclick("Bottom"); -#if 0 // https://stackoverflow.com/questions/32305678/x3dom-how-to-make-zoom-buttons +#if 0 // https://stackoverflow.com/questions/32305678/x3dom-how-to-make-zoom-buttons function zoom (delta) { var x3d = document.getElementById("right"); var vpt = x3d.getElementsByTagName("Viewpoint")[0]; @@ -2864,10 +3032,11 @@ bool MeshOutput::SaveX3DOM (std::ostream &out) const } /** Writes a Nastran file. */ -bool MeshOutput::SaveNastran (std::ostream &rstrOut) const +bool MeshOutput::SaveNastran(std::ostream& rstrOut) const { - if (!rstrOut || rstrOut.bad() || (_rclMesh.CountFacets() == 0)) + if (!rstrOut || rstrOut.bad() || (_rclMesh.CountFacets() == 0)) { return false; + } MeshPointIterator clPIter(_rclMesh); clPIter.Transform(this->_transform); @@ -2887,8 +3056,8 @@ bool MeshOutput::SaveNastran (std::ostream &rstrOut) const rstrOut << std::setfill(' ') << std::setw(12) << iIndx; rstrOut << std::setfill(' ') << std::setw(16) << x; - rstrOut << std::setfill(' ') << std::setw(8) << y; - rstrOut << std::setfill(' ') << std::setw(8) << z; + rstrOut << std::setfill(' ') << std::setw(8) << y; + rstrOut << std::setfill(' ') << std::setw(8) << z; rstrOut << '\n'; iIndx++; @@ -2901,9 +3070,9 @@ bool MeshOutput::SaveNastran (std::ostream &rstrOut) const rstrOut << std::setfill(' ') << std::setw(10) << iIndx; rstrOut << std::setfill(' ') << std::setw(8) << (int)0; - rstrOut << std::setfill(' ') << std::setw(8) << clTIter.GetIndices()._aulPoints[1]+1; - rstrOut << std::setfill(' ') << std::setw(8) << clTIter.GetIndices()._aulPoints[0]+1; - rstrOut << std::setfill(' ') << std::setw(8) << clTIter.GetIndices()._aulPoints[2]+1; + rstrOut << std::setfill(' ') << std::setw(8) << clTIter.GetIndices()._aulPoints[1] + 1; + rstrOut << std::setfill(' ') << std::setw(8) << clTIter.GetIndices()._aulPoints[0] + 1; + rstrOut << std::setfill(' ') << std::setw(8) << clTIter.GetIndices()._aulPoints[2] + 1; rstrOut << '\n'; iIndx++; @@ -2916,16 +3085,17 @@ bool MeshOutput::SaveNastran (std::ostream &rstrOut) const } /** Writes a Cadmould FE file. */ -bool MeshOutput::SaveCadmouldFE (std::ostream & /*rstrOut*/) const +bool MeshOutput::SaveCadmouldFE(std::ostream& /*rstrOut*/) const { return false; } /** Writes a Python module */ -bool MeshOutput::SavePython (std::ostream &str) const +bool MeshOutput::SavePython(std::ostream& str) const { - if (!str || str.bad() || (_rclMesh.CountFacets() == 0)) + if (!str || str.bad() || (_rclMesh.CountFacets() == 0)) { return false; + } MeshFacetIterator clIter(_rclMesh); clIter.Transform(this->_transform); @@ -2936,10 +3106,7 @@ bool MeshOutput::SavePython (std::ostream &str) const for (clIter.Init(); clIter.More(); clIter.Next()) { const MeshGeomFacet& rFacet = *clIter; for (const auto& pnt : rFacet._aclPoints) { - str << "[" << pnt.x - << "," << pnt.y - << "," << pnt.z - << "],"; + str << "[" << pnt.x << "," << pnt.y << "," << pnt.z << "],"; } str << '\n'; } @@ -2950,15 +3117,16 @@ bool MeshOutput::SavePython (std::ostream &str) const } /** Writes a VRML file. */ -bool MeshOutput::SaveVRML (std::ostream &rstrOut) const +bool MeshOutput::SaveVRML(std::ostream& rstrOut) const { - if (!rstrOut || rstrOut.bad() || (_rclMesh.CountFacets() == 0)) + if (!rstrOut || rstrOut.bad() || (_rclMesh.CountFacets() == 0)) { return false; + } Base::BoundBox3f clBB = _rclMesh.GetBoundBox(); Base::SequencerLauncher seq("Saving VRML file...", - _rclMesh.CountPoints() + _rclMesh.CountFacets()); + _rclMesh.CountPoints() + _rclMesh.CountFacets()); rstrOut << "#VRML V2.0 utf8\n"; rstrOut << "WorldInfo {\n" @@ -2974,14 +3142,8 @@ bool MeshOutput::SaveVRML (std::ostream &rstrOut) const << " scale 1 1 1\n" << " rotation 0 0 1 0\n" << " scaleOrientation 0 0 1 0\n" - << " center " - << 0.0f << " " - << 0.0f << " " - << 0.0f << "\n" - << " translation " - << 0.0f << " " - << 0.0f << " " - << 0.0f << "\n"; + << " center " << 0.0f << " " << 0.0f << " " << 0.0f << "\n" + << " translation " << 0.0f << " " << 0.0f << " " << 0.0f << "\n"; rstrOut << " children\n"; rstrOut << " Shape { \n"; @@ -2994,10 +3156,7 @@ bool MeshOutput::SaveVRML (std::ostream &rstrOut) const if (_material && _material->binding == MeshIO::OVERALL) { if (!_material->diffuseColor.empty()) { App::Color c = _material->diffuseColor.front(); - rstrOut << " diffuseColor " - << c.r << " " - << c.g << " " - << c.b << "\n"; + rstrOut << " diffuseColor " << c.r << " " << c.g << " " << c.b << "\n"; } else { rstrOut << " diffuseColor 0.8 0.8 0.8\n"; @@ -3006,7 +3165,7 @@ bool MeshOutput::SaveVRML (std::ostream &rstrOut) const else { rstrOut << " diffuseColor 0.8 0.8 0.8\n"; } - rstrOut << " }\n }\n"; // end write appearance + rstrOut << " }\n }\n"; // end write appearance // write IndexedFaceSet @@ -3024,14 +3183,13 @@ bool MeshOutput::SaveVRML (std::ostream &rstrOut) const rstrOut.precision(3); rstrOut.setf(std::ios::fixed | std::ios::showpoint); for (pPIter.Init(); pPIter.More(); pPIter.Next()) { - rstrOut << " " - << pPIter->x << " " - << pPIter->y << " " - << pPIter->z; - if (i++ < (k-1)) + rstrOut << " " << pPIter->x << " " << pPIter->y << " " << pPIter->z; + if (i++ < (k - 1)) { rstrOut << ",\n"; - else + } + else { rstrOut << "\n"; + } seq.next(); } @@ -3044,22 +3202,25 @@ bool MeshOutput::SaveVRML (std::ostream &rstrOut) const rstrOut.precision(3); rstrOut.setf(std::ios::fixed | std::ios::showpoint); for (std::vector::const_iterator pCIter = _material->diffuseColor.begin(); - pCIter != _material->diffuseColor.end(); ++pCIter) { - rstrOut << " " - << float(pCIter->r) << " " - << float(pCIter->g) << " " + pCIter != _material->diffuseColor.end(); + ++pCIter) { + rstrOut << " " << float(pCIter->r) << " " << float(pCIter->g) << " " << float(pCIter->b); - if (pCIter < (_material->diffuseColor.end() - 1)) + if (pCIter < (_material->diffuseColor.end() - 1)) { rstrOut << ",\n"; - else + } + else { rstrOut << "\n"; + } } rstrOut << " ]\n }\n"; - if (_material->binding == MeshIO::PER_VERTEX) + if (_material->binding == MeshIO::PER_VERTEX) { rstrOut << " colorPerVertex TRUE\n"; - else + } + else { rstrOut << " colorPerVertex FALSE\n"; + } } // write face index @@ -3070,21 +3231,21 @@ bool MeshOutput::SaveVRML (std::ostream &rstrOut) const for (pFIter.Init(); pFIter.More(); pFIter.Next()) { MeshFacet clFacet = pFIter.GetIndices(); - rstrOut << " " - << clFacet._aulPoints[0] << ", " - << clFacet._aulPoints[1] << ", " + rstrOut << " " << clFacet._aulPoints[0] << ", " << clFacet._aulPoints[1] << ", " << clFacet._aulPoints[2] << ", -1"; - if (i++ < (k-1)) + if (i++ < (k - 1)) { rstrOut << ",\n"; - else + } + else { rstrOut << "\n"; + } seq.next(); } rstrOut << " ]\n }\n"; // End IndexedFaceSet - rstrOut << " }\n"; // End Shape - rstrOut << "}\n"; // close children and Transform + rstrOut << " }\n"; // End Shape + rstrOut << "}\n"; // close children and Transform return true; } @@ -3092,10 +3253,9 @@ bool MeshOutput::SaveVRML (std::ostream &rstrOut) const // ---------------------------------------------------------------------------- MeshCleanup::MeshCleanup(MeshPointArray& p, MeshFacetArray& f) - : pointArray(p) - , facetArray(f) -{ -} + : pointArray(p) + , facetArray(f) +{} void MeshCleanup::SetMaterial(Material* mat) { @@ -3111,7 +3271,7 @@ void MeshCleanup::RemoveInvalids() // Now go through the facets and invalidate facets with wrong indices // If a facet is valid all its referenced points are validated again // Points that are not referenced are still invalid and thus can be deleted - for (auto & it : facetArray) { + for (auto& it : facetArray) { for (PointIndex point : it._aulPoints) { // vertex index out of range if (point >= numPoints) { @@ -3136,13 +3296,15 @@ void MeshCleanup::RemoveInvalids() void MeshCleanup::RemoveInvalidFacets() { MeshIsFlag flag; - std::size_t countInvalidFacets = std::count_if(facetArray.begin(), facetArray.end(), - [flag](const MeshFacet& f) { return flag(f, MeshFacet::INVALID); }); + std::size_t countInvalidFacets = + std::count_if(facetArray.begin(), facetArray.end(), [flag](const MeshFacet& f) { + return flag(f, MeshFacet::INVALID); + }); if (countInvalidFacets > 0) { // adjust the material array if needed - if (materialArray && materialArray->binding == MeshIO::PER_FACE && - materialArray->diffuseColor.size() == facetArray.size()) { + if (materialArray && materialArray->binding == MeshIO::PER_FACE + && materialArray->diffuseColor.size() == facetArray.size()) { std::vector colors; colors.reserve(facetArray.size() - countInvalidFacets); for (std::size_t index = 0; index < facetArray.size(); index++) { @@ -3156,8 +3318,12 @@ void MeshCleanup::RemoveInvalidFacets() MeshFacetArray copy_facets(facetArray.size() - countInvalidFacets); // copy all valid facets to the new array - std::remove_copy_if(facetArray.begin(), facetArray.end(), copy_facets.begin(), - [flag](const MeshFacet& f) { return flag(f, MeshFacet::INVALID); }); + std::remove_copy_if(facetArray.begin(), + facetArray.end(), + copy_facets.begin(), + [flag](const MeshFacet& f) { + return flag(f, MeshFacet::INVALID); + }); facetArray.swap(copy_facets); } } @@ -3165,8 +3331,10 @@ void MeshCleanup::RemoveInvalidFacets() void MeshCleanup::RemoveInvalidPoints() { MeshIsFlag flag; - std::size_t countInvalidPoints = std::count_if(pointArray.begin(), pointArray.end(), - [flag](const MeshPoint& p) { return flag(p, MeshPoint::INVALID); }); + std::size_t countInvalidPoints = + std::count_if(pointArray.begin(), pointArray.end(), [flag](const MeshPoint& p) { + return flag(p, MeshPoint::INVALID); + }); if (countInvalidPoints > 0) { // generate array of decrements std::vector decrements; @@ -3175,10 +3343,12 @@ void MeshCleanup::RemoveInvalidPoints() MeshPointArray::_TIterator p_end = pointArray.end(); std::vector::iterator decr_it = decrements.begin(); - for (MeshPointArray::_TIterator p_it = pointArray.begin(); p_it != p_end; ++p_it, ++decr_it) { + for (MeshPointArray::_TIterator p_it = pointArray.begin(); p_it != p_end; + ++p_it, ++decr_it) { *decr_it = decr; - if (!p_it->IsValid()) + if (!p_it->IsValid()) { decr++; + } } // correct point indices of the facets @@ -3193,8 +3363,8 @@ void MeshCleanup::RemoveInvalidPoints() std::size_t validPoints = pointArray.size() - countInvalidPoints; // adjust the material array if needed - if (materialArray && materialArray->binding == MeshIO::PER_VERTEX && - materialArray->diffuseColor.size() == pointArray.size()) { + if (materialArray && materialArray->binding == MeshIO::PER_VERTEX + && materialArray->diffuseColor.size() == pointArray.size()) { std::vector colors; colors.reserve(validPoints); for (std::size_t index = 0; index < pointArray.size(); index++) { @@ -3208,8 +3378,12 @@ void MeshCleanup::RemoveInvalidPoints() MeshPointArray copy_points(validPoints); // copy all valid facets to the new array - std::remove_copy_if(pointArray.begin(), pointArray.end(), copy_points.begin(), - [flag](const MeshPoint& p) { return flag(p, MeshPoint::INVALID); }); + std::remove_copy_if(pointArray.begin(), + pointArray.end(), + copy_points.begin(), + [flag](const MeshPoint& p) { + return flag(p, MeshPoint::INVALID); + }); pointArray.swap(copy_points); } } @@ -3217,8 +3391,8 @@ void MeshCleanup::RemoveInvalidPoints() // ---------------------------------------------------------------------------- MeshPointFacetAdjacency::MeshPointFacetAdjacency(std::size_t p, MeshFacetArray& f) - : numPoints(p) - , facets(f) + : numPoints(p) + , facets(f) { Build(); } @@ -3226,15 +3400,16 @@ MeshPointFacetAdjacency::MeshPointFacetAdjacency(std::size_t p, MeshFacetArray& void MeshPointFacetAdjacency::Build() { std::vector numFacetAdjacency(numPoints); - for (const auto & it : facets) { + for (const auto& it : facets) { numFacetAdjacency[it._aulPoints[0]]++; numFacetAdjacency[it._aulPoints[1]]++; numFacetAdjacency[it._aulPoints[2]]++; } pointFacetAdjacency.resize(numPoints); - for (std::size_t i = 0; i < numPoints; i++) + for (std::size_t i = 0; i < numPoints; i++) { pointFacetAdjacency[i].reserve(numFacetAdjacency[i]); + } std::size_t numFacets = facets.size(); for (std::size_t i = 0; i < numFacets; i++) { @@ -3251,7 +3426,7 @@ void MeshPointFacetAdjacency::SetFacetNeighbourhood() MeshFacet& facet1 = facets[index]; for (int i = 0; i < 3; i++) { std::size_t n1 = facet1._aulPoints[i]; - std::size_t n2 = facet1._aulPoints[(i+1)%3]; + std::size_t n2 = facet1._aulPoints[(i + 1) % 3]; bool success = false; const std::vector& refFacets = pointFacetAdjacency[n1]; diff --git a/src/Mod/Mesh/App/Core/MeshIO.h b/src/Mod/Mesh/App/Core/MeshIO.h index 7f3e38a5e6..8f110d1008 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.h +++ b/src/Mod/Mesh/App/Core/MeshIO.h @@ -29,52 +29,57 @@ #include "MeshKernel.h" -namespace Base { +namespace Base +{ class XMLReader; class Writer; -} +} // namespace Base -namespace MeshCore { +namespace MeshCore +{ class MeshKernel; -namespace MeshIO { - enum Format { - Undefined, - BMS, - ASTL, - BSTL, - STL, - OBJ, - OFF, - IDTF, - MGL, - IV, - X3D, - X3DZ, - X3DOM, - VRML, - WRZ, - NAS, - PLY, - APLY, - PY, - AMF, - SMF, - ASY, - ThreeMF - }; - enum Binding { - OVERALL, - PER_VERTEX, - PER_FACE - }; -} +namespace MeshIO +{ +enum Format +{ + Undefined, + BMS, + ASTL, + BSTL, + STL, + OBJ, + OFF, + IDTF, + MGL, + IV, + X3D, + X3DZ, + X3DOM, + VRML, + WRZ, + NAS, + PLY, + APLY, + PY, + AMF, + SMF, + ASY, + ThreeMF +}; +enum Binding +{ + OVERALL, + PER_VERTEX, + PER_FACE +}; +} // namespace MeshIO struct MeshExport Material { Material() = default; - MeshIO::Binding binding{MeshIO::OVERALL}; + MeshIO::Binding binding {MeshIO::OVERALL}; mutable std::string library; std::vector ambientColor; /**< Defines the ambient color. */ @@ -84,8 +89,8 @@ struct MeshExport Material std::vector shininess; std::vector transparency; - bool operator == (const Material& mat) const; - bool operator != (const Material& mat) const; + bool operator==(const Material& mat) const; + bool operator!=(const Material& mat) const; }; struct MeshExport Group @@ -101,54 +106,59 @@ struct MeshExport Group class MeshExport MeshInput { public: - explicit MeshInput (MeshKernel &rclM) - : _rclMesh(rclM), _material(nullptr){} - MeshInput (MeshKernel &rclM, Material* m) - : _rclMesh(rclM), _material(m){} - const std::vector& GetGroupNames() const { + explicit MeshInput(MeshKernel& rclM) + : _rclMesh(rclM) + , _material(nullptr) + {} + MeshInput(MeshKernel& rclM, Material* m) + : _rclMesh(rclM) + , _material(m) + {} + const std::vector& GetGroupNames() const + { return _groupNames; } /// Loads the file, decided by extension bool LoadAny(const char* FileName); /// Loads from a stream and the given format - bool LoadFormat(std::istream &str, MeshIO::Format fmt); + bool LoadFormat(std::istream& str, MeshIO::Format fmt); /** Loads an STL file either in binary or ASCII format. * Therefore the file header gets checked to decide if the file is binary or not. */ - bool LoadSTL (std::istream &rstrIn); + bool LoadSTL(std::istream& rstrIn); /** Loads an ASCII STL file. */ - bool LoadAsciiSTL (std::istream &rstrIn); + bool LoadAsciiSTL(std::istream& rstrIn); /** Loads a binary STL file. */ - bool LoadBinarySTL (std::istream &rstrIn); + bool LoadBinarySTL(std::istream& rstrIn); /** Loads an OBJ Mesh file. */ - bool LoadOBJ (std::istream &rstrIn); + bool LoadOBJ(std::istream& rstrIn); /** Loads an OBJ Mesh file. */ - bool LoadOBJ (std::istream &rstrIn, const char* filename); + bool LoadOBJ(std::istream& rstrIn, const char* filename); /** Loads an SMF Mesh file. */ - bool LoadSMF (std::istream &rstrIn); + bool LoadSMF(std::istream& rstrIn); /** Loads an OFF Mesh file. */ - bool LoadOFF (std::istream &rstrIn); + bool LoadOFF(std::istream& rstrIn); /** Loads a PLY Mesh file. */ - bool LoadPLY (std::istream &rstrIn); + bool LoadPLY(std::istream& rstrIn); /** Loads the mesh object from an XML file. */ - void LoadXML (Base::XMLReader &reader); + void LoadXML(Base::XMLReader& reader); /** Loads the mesh object from a 3MF file. */ - bool Load3MF (std::istream &str); + bool Load3MF(std::istream& str); /** Loads a node from an OpenInventor file. */ - bool LoadMeshNode (std::istream &rstrIn); + bool LoadMeshNode(std::istream& rstrIn); /** Loads an OpenInventor file. */ - bool LoadInventor (std::istream &rstrIn); + bool LoadInventor(std::istream& rstrIn); /** Loads a Nastran file. */ - bool LoadNastran (std::istream &rstrIn); + bool LoadNastran(std::istream& rstrIn); /** Loads a Cadmould FE file. */ - bool LoadCadmouldFE (std::ifstream &rstrIn); + bool LoadCadmouldFE(std::ifstream& rstrIn); static std::vector supportedMeshFormats(); static MeshIO::Format getFormat(const char* FileName); protected: - MeshKernel &_rclMesh; /**< reference to mesh data structure */ + MeshKernel& _rclMesh; /**< reference to mesh data structure */ Material* _material; std::vector _groupNames; }; @@ -160,13 +170,22 @@ protected: class MeshExport MeshOutput { public: - explicit MeshOutput (const MeshKernel &rclM) - : _rclMesh(rclM), _material(nullptr), apply_transform(false){} - MeshOutput (const MeshKernel &rclM, const Material* m) - : _rclMesh(rclM), _material(m), apply_transform(false){} + explicit MeshOutput(const MeshKernel& rclM) + : _rclMesh(rclM) + , _material(nullptr) + , apply_transform(false) + {} + MeshOutput(const MeshKernel& rclM, const Material* m) + : _rclMesh(rclM) + , _material(m) + , apply_transform(false) + {} void SetObjectName(const std::string& n) - { objectName = n; } - void SetGroups(const std::vector& g) { + { + objectName = n; + } + void SetGroups(const std::vector& g) + { _groups = g; } @@ -184,61 +203,61 @@ public: /// Determine the mesh format by file extension static MeshIO::Format GetFormat(const char* FileName); /// Saves the file, decided by extension if not explicitly given - bool SaveAny(const char* FileName, MeshIO::Format f=MeshIO::Undefined) const; + bool SaveAny(const char* FileName, MeshIO::Format f = MeshIO::Undefined) const; /// Saves to a stream and the given format - bool SaveFormat(std::ostream &str, MeshIO::Format fmt) const; + bool SaveFormat(std::ostream& str, MeshIO::Format fmt) const; /** Saves the mesh object into an ASCII STL file. */ - bool SaveAsciiSTL (std::ostream &rstrOut) const; + bool SaveAsciiSTL(std::ostream& rstrOut) const; /** Saves the mesh object into a binary STL file. */ - bool SaveBinarySTL (std::ostream &rstrOut) const; + bool SaveBinarySTL(std::ostream& rstrOut) const; /** Saves the mesh object into an OBJ file. */ - bool SaveOBJ (std::ostream &rstrOut) const; + bool SaveOBJ(std::ostream& rstrOut) const; /** Saves the mesh object into an OBJ file. */ - bool SaveOBJ (std::ostream &rstrOut, const char* filename) const; + bool SaveOBJ(std::ostream& rstrOut, const char* filename) const; /** Saves the mesh object into an SMF file. */ - bool SaveSMF (std::ostream &rstrOut) const; + bool SaveSMF(std::ostream& rstrOut) const; /** Saves the mesh object into an OFF file. */ - bool SaveOFF (std::ostream &rstrOut) const; + bool SaveOFF(std::ostream& rstrOut) const; /** Saves the mesh object into a binary PLY file. */ - bool SaveBinaryPLY (std::ostream &rstrOut) const; + bool SaveBinaryPLY(std::ostream& rstrOut) const; /** Saves the mesh object into an ASCII PLY file. */ - bool SaveAsciiPLY (std::ostream &rstrOut) const; + bool SaveAsciiPLY(std::ostream& rstrOut) const; /** Saves the mesh object into an asymptote file. */ - bool SaveAsymptote (std::ostream &rstrOut) const; + bool SaveAsymptote(std::ostream& rstrOut) const; /** Saves the mesh object into an XML file. */ - void SaveXML (Base::Writer &writer) const; + void SaveXML(Base::Writer& writer) const; /** Saves the mesh object into a 3MF file. */ - bool Save3MF (std::ostream &str) const; + bool Save3MF(std::ostream& str) const; /** Saves a node to an OpenInventor file. */ - bool SaveMeshNode (std::ostream &rstrIn); + bool SaveMeshNode(std::ostream& rstrIn); /** Writes an IDTF file. */ - bool SaveIDTF (std::ostream &rstrOut) const; + bool SaveIDTF(std::ostream& rstrOut) const; /** Writes an MGL file. */ - bool SaveMGL (std::ostream &rstrOut) const; + bool SaveMGL(std::ostream& rstrOut) const; /** Writes an OpenInventor file. */ - bool SaveInventor (std::ostream &rstrOut) const; + bool SaveInventor(std::ostream& rstrOut) const; /** Writes an X3D file. */ - bool SaveX3D (std::ostream &rstrOut) const; + bool SaveX3D(std::ostream& rstrOut) const; /** Writes an X3dom file. */ - bool SaveX3DOM (std::ostream &rstrOut) const; + bool SaveX3DOM(std::ostream& rstrOut) const; /** Writes a VRML file. */ - bool SaveVRML (std::ostream &rstrOut) const; + bool SaveVRML(std::ostream& rstrOut) const; /** Writes a Nastran file. */ - bool SaveNastran (std::ostream &rstrOut) const; + bool SaveNastran(std::ostream& rstrOut) const; /** Writes a Cadmould FE file. */ - bool SaveCadmouldFE (std::ostream &rstrOut) const; + bool SaveCadmouldFE(std::ostream& rstrOut) const; /** Writes a python module which creates a mesh */ - bool SavePython (std::ostream &rstrOut) const; + bool SavePython(std::ostream& rstrOut) const; static std::vector supportedMeshFormats(); protected: /** Writes an X3D file. */ - bool SaveX3DContent (std::ostream &rstrOut, bool exportViewpoints) const; + bool SaveX3DContent(std::ostream& rstrOut, bool exportViewpoints) const; protected: - const MeshKernel &_rclMesh; /**< reference to mesh data structure */ + const MeshKernel& _rclMesh; /**< reference to mesh data structure */ const Material* _material; Base::Matrix4D _transform; bool apply_transform; @@ -289,7 +308,7 @@ private: private: MeshPointArray& pointArray; MeshFacetArray& facetArray; - Material* materialArray{nullptr}; + Material* materialArray {nullptr}; }; /*! @@ -322,10 +341,10 @@ private: private: std::size_t numPoints; MeshFacetArray& facets; - std::vector< std::vector > pointFacetAdjacency; + std::vector> pointFacetAdjacency; }; -} // namespace MeshCore +} // namespace MeshCore -#endif // MESH_IO_H +#endif // MESH_IO_H diff --git a/src/Mod/Mesh/App/Core/MeshKernel.cpp b/src/Mod/Mesh/App/Core/MeshKernel.cpp index 45063ddf86..f760c75ad0 100644 --- a/src/Mod/Mesh/App/Core/MeshKernel.cpp +++ b/src/Mod/Mesh/App/Core/MeshKernel.cpp @@ -23,22 +23,22 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include -# include +#include +#include +#include +#include #endif #include #include #include -#include "MeshKernel.h" #include "Algorithm.h" #include "Builder.h" #include "Evaluation.h" #include "Iterator.h" #include "MeshIO.h" +#include "MeshKernel.h" #include "Smoothing.h" @@ -49,42 +49,46 @@ MeshKernel::MeshKernel() _clBoundBox.SetVoid(); } -MeshKernel::MeshKernel (const MeshKernel &rclMesh) +MeshKernel::MeshKernel(const MeshKernel& rclMesh) { *this = rclMesh; } -MeshKernel& MeshKernel::operator = (const MeshKernel &rclMesh) +MeshKernel& MeshKernel::operator=(const MeshKernel& rclMesh) { - if (this != &rclMesh) { // must be a different instance - this->_aclPointArray = rclMesh._aclPointArray; - this->_aclFacetArray = rclMesh._aclFacetArray; - this->_clBoundBox = rclMesh._clBoundBox; - this->_bValid = rclMesh._bValid; + if (this != &rclMesh) { // must be a different instance + this->_aclPointArray = rclMesh._aclPointArray; + this->_aclFacetArray = rclMesh._aclFacetArray; + this->_clBoundBox = rclMesh._clBoundBox; + this->_bValid = rclMesh._bValid; } return *this; } -MeshKernel& MeshKernel::operator = (const std::vector &rclFAry) +MeshKernel& MeshKernel::operator=(const std::vector& rclFAry) { MeshBuilder builder(*this); builder.Initialize(rclFAry.size()); - for (const auto & it : rclFAry) + for (const auto& it : rclFAry) { builder.AddFacet(it); + } builder.Finish(); return *this; } -void MeshKernel::Assign(const MeshPointArray& rPoints, const MeshFacetArray& rFacets, bool checkNeighbourHood) +void MeshKernel::Assign(const MeshPointArray& rPoints, + const MeshFacetArray& rFacets, + bool checkNeighbourHood) { _aclPointArray = rPoints; _aclFacetArray = rFacets; RecalcBoundBox(); - if (checkNeighbourHood) + if (checkNeighbourHood) { RebuildNeighbours(); + } } void MeshKernel::Adopt(MeshPointArray& rPoints, MeshFacetArray& rFacets, bool checkNeighbourHood) @@ -92,8 +96,9 @@ void MeshKernel::Adopt(MeshPointArray& rPoints, MeshFacetArray& rFacets, bool ch _aclPointArray.swap(rPoints); _aclFacetArray.swap(rFacets); RecalcBoundBox(); - if (checkNeighbourHood) + if (checkNeighbourHood) { RebuildNeighbours(); + } } void MeshKernel::Swap(MeshKernel& mesh) @@ -103,13 +108,13 @@ void MeshKernel::Swap(MeshKernel& mesh) this->_clBoundBox = mesh._clBoundBox; } -MeshKernel& MeshKernel::operator += (const MeshGeomFacet &rclSFacet) +MeshKernel& MeshKernel::operator+=(const MeshGeomFacet& rclSFacet) { this->AddFacet(rclSFacet); return *this; } -void MeshKernel::AddFacet(const MeshGeomFacet &rclSFacet) +void MeshKernel::AddFacet(const MeshGeomFacet& rclSFacet) { MeshFacet clFacet; @@ -129,10 +134,11 @@ void MeshKernel::AddFacet(const MeshGeomFacet &rclSFacet) PointIndex ulP1 = clFacet._aulPoints[1]; PointIndex ulP2 = clFacet._aulPoints[2]; FacetIndex ulCC = 0; - for (TMeshFacetArray::iterator pF = _aclFacetArray.begin(); pF != _aclFacetArray.end(); ++pF, ulCC++) { - for (int i=0; i<3;i++) { + for (TMeshFacetArray::iterator pF = _aclFacetArray.begin(); pF != _aclFacetArray.end(); + ++pF, ulCC++) { + for (int i = 0; i < 3; i++) { PointIndex ulP = pF->_aulPoints[i]; - PointIndex ulQ = pF->_aulPoints[(i+1)%3]; + PointIndex ulQ = pF->_aulPoints[(i + 1) % 3]; if (ulQ == ulP0 && ulP == ulP1) { clFacet._aulNeighbours[0] = ulCC; pF->_aulNeighbours[i] = ulCt; @@ -152,13 +158,13 @@ void MeshKernel::AddFacet(const MeshGeomFacet &rclSFacet) _aclFacetArray.push_back(clFacet); } -MeshKernel& MeshKernel::operator += (const std::vector &rclFAry) +MeshKernel& MeshKernel::operator+=(const std::vector& rclFAry) { this->AddFacets(rclFAry); return *this; } -void MeshKernel::AddFacets(const std::vector &rclFAry) +void MeshKernel::AddFacets(const std::vector& rclFAry) { // Create a temp. kernel to get the topology of the passed triangles // and merge them with this kernel. This keeps properties and flags @@ -168,8 +174,7 @@ void MeshKernel::AddFacets(const std::vector &rclFAry) Merge(tmp); } -unsigned long MeshKernel::AddFacets(const std::vector &rclFAry, - bool checkManifolds) +unsigned long MeshKernel::AddFacets(const std::vector& rclFAry, bool checkManifolds) { // Build map of edges of the referencing facets we want to append #ifdef FC_DEBUG @@ -183,7 +188,7 @@ unsigned long MeshKernel::AddFacets(const std::vector &rclFAry, _aclFacetArray.reserve(countFacets + countValid); // just add all faces now - for (const auto & pF : rclFAry) { + for (const auto& pF : rclFAry) { _aclFacetArray.push_back(pF); } @@ -193,17 +198,18 @@ unsigned long MeshKernel::AddFacets(const std::vector &rclFAry, this->_aclPointArray.ResetInvalid(); FacetIndex k = CountFacets(); - std::map, std::list > edgeMap; - for (std::vector::const_iterator pF = rclFAry.begin(); pF != rclFAry.end(); ++pF, k++) { + std::map, std::list> edgeMap; + for (std::vector::const_iterator pF = rclFAry.begin(); pF != rclFAry.end(); + ++pF, k++) { // reset INVALID flag for all candidates pF->ResetFlag(MeshFacet::INVALID); - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { #ifdef FC_DEBUG - assert( pF->_aulPoints[i] < countPoints ); + assert(pF->_aulPoints[i] < countPoints); #endif this->_aclPointArray[pF->_aulPoints[i]].SetFlag(MeshPoint::INVALID); PointIndex ulT0 = pF->_aulPoints[i]; - PointIndex ulT1 = pF->_aulPoints[(i+1)%3]; + PointIndex ulT1 = pF->_aulPoints[(i + 1) % 3]; PointIndex ulP0 = std::min(ulT0, ulT1); PointIndex ulP1 = std::max(ulT0, ulT1); edgeMap[std::make_pair(ulP0, ulP1)].push_front(k); @@ -211,20 +217,23 @@ unsigned long MeshKernel::AddFacets(const std::vector &rclFAry, } // Check for the above edges in the current facet array - k=0; - for (MeshFacetArray::_TIterator pF = _aclFacetArray.begin(); pF != _aclFacetArray.end(); ++pF, k++) { + k = 0; + for (MeshFacetArray::_TIterator pF = _aclFacetArray.begin(); pF != _aclFacetArray.end(); + ++pF, k++) { // if none of the points references one of the edges ignore the facet - if (!this->_aclPointArray[pF->_aulPoints[0]].IsFlag(MeshPoint::INVALID) && - !this->_aclPointArray[pF->_aulPoints[1]].IsFlag(MeshPoint::INVALID) && - !this->_aclPointArray[pF->_aulPoints[2]].IsFlag(MeshPoint::INVALID)) + if (!this->_aclPointArray[pF->_aulPoints[0]].IsFlag(MeshPoint::INVALID) + && !this->_aclPointArray[pF->_aulPoints[1]].IsFlag(MeshPoint::INVALID) + && !this->_aclPointArray[pF->_aulPoints[2]].IsFlag(MeshPoint::INVALID)) { continue; - for (int i=0; i<3; i++) { + } + for (int i = 0; i < 3; i++) { PointIndex ulT0 = pF->_aulPoints[i]; - PointIndex ulT1 = pF->_aulPoints[(i+1)%3]; + PointIndex ulT1 = pF->_aulPoints[(i + 1) % 3]; PointIndex ulP0 = std::min(ulT0, ulT1); PointIndex ulP1 = std::max(ulT0, ulT1); std::pair edge = std::make_pair(ulP0, ulP1); - std::map, std::list >::iterator pI = edgeMap.find(edge); + std::map, std::list>::iterator pI = + edgeMap.find(edge); // Does the current facet share the same edge? if (pI != edgeMap.end()) { pI->second.push_front(k); @@ -234,15 +243,13 @@ unsigned long MeshKernel::AddFacets(const std::vector &rclFAry, this->_aclPointArray.ResetInvalid(); - // Now let's see for which edges we might get manifolds, if so we don't add the corresponding candidates + // Now let's see for which edges we might get manifolds, if so we don't add the corresponding + // candidates FacetIndex countFacets = CountFacets(); - std::map, std::list >::iterator pE; - for (pE = edgeMap.begin(); pE != edgeMap.end(); ++pE) - { - if (pE->second.size() > 2) - { - for (FacetIndex it : pE->second) - { + std::map, std::list>::iterator pE; + for (pE = edgeMap.begin(); pE != edgeMap.end(); ++pE) { + if (pE->second.size() > 2) { + for (FacetIndex it : pE->second) { if (it >= countFacets) { // this is a candidate FacetIndex index = it - countFacets; @@ -255,13 +262,15 @@ unsigned long MeshKernel::AddFacets(const std::vector &rclFAry, // Do not insert directly to the data structure because we should get the correct size of new // facets, otherwise std::vector reallocates too much memory which can't be freed so easily MeshIsNotFlag flag; - FacetIndex countValid = std::count_if(rclFAry.begin(), rclFAry.end(), [flag](const MeshFacet& f) { - return flag(f, MeshFacet::INVALID); - }); - _aclFacetArray.reserve( _aclFacetArray.size() + countValid ); - // now start inserting the facets to the data structure and set the correct neighbourhood as well + FacetIndex countValid = + std::count_if(rclFAry.begin(), rclFAry.end(), [flag](const MeshFacet& f) { + return flag(f, MeshFacet::INVALID); + }); + _aclFacetArray.reserve(_aclFacetArray.size() + countValid); + // now start inserting the facets to the data structure and set the correct neighbourhood as + // well FacetIndex startIndex = CountFacets(); - for (const auto & pF : rclFAry) { + for (const auto& pF : rclFAry) { if (!pF.IsFlag(MeshFacet::INVALID)) { _aclFacetArray.push_back(pF); pF.SetProperty(startIndex++); @@ -269,8 +278,7 @@ unsigned long MeshKernel::AddFacets(const std::vector &rclFAry, } // resolve neighbours - for (pE = edgeMap.begin(); pE != edgeMap.end(); ++pE) - { + for (pE = edgeMap.begin(); pE != edgeMap.end(); ++pE) { PointIndex ulP0 = pE->first.first; PointIndex ulP1 = pE->first.second; if (pE->second.size() == 1) // border facet @@ -279,14 +287,16 @@ unsigned long MeshKernel::AddFacets(const std::vector &rclFAry, if (ulF0 >= countFacets) { ulF0 -= countFacets; std::vector::const_iterator pF = rclFAry.begin() + ulF0; - if (!pF->IsFlag(MeshFacet::INVALID)) + if (!pF->IsFlag(MeshFacet::INVALID)) { ulF0 = pF->_ulProp; - else + } + else { ulF0 = FACET_INDEX_MAX; + } } if (ulF0 != FACET_INDEX_MAX) { - unsigned short usSide = _aclFacetArray[ulF0].Side(ulP0, ulP1); + unsigned short usSide = _aclFacetArray[ulF0].Side(ulP0, ulP1); assert(usSide != USHRT_MAX); _aclFacetArray[ulF0]._aulNeighbours[usSide] = FACET_INDEX_MAX; } @@ -298,19 +308,23 @@ unsigned long MeshKernel::AddFacets(const std::vector &rclFAry, if (ulF0 >= countFacets) { ulF0 -= countFacets; std::vector::const_iterator pF = rclFAry.begin() + ulF0; - if (!pF->IsFlag(MeshFacet::INVALID)) + if (!pF->IsFlag(MeshFacet::INVALID)) { ulF0 = pF->_ulProp; - else + } + else { ulF0 = FACET_INDEX_MAX; + } } FacetIndex ulF1 = pE->second.back(); if (ulF1 >= countFacets) { ulF1 -= countFacets; std::vector::const_iterator pF = rclFAry.begin() + ulF1; - if (!pF->IsFlag(MeshFacet::INVALID)) + if (!pF->IsFlag(MeshFacet::INVALID)) { ulF1 = pF->_ulProp; - else + } + else { ulF1 = FACET_INDEX_MAX; + } } if (ulF0 != FACET_INDEX_MAX) { @@ -330,12 +344,13 @@ unsigned long MeshKernel::AddFacets(const std::vector &rclFAry, return _aclFacetArray.size(); } -unsigned long MeshKernel::AddFacets(const std::vector &rclFAry, +unsigned long MeshKernel::AddFacets(const std::vector& rclFAry, const std::vector& rclPAry, bool checkManifolds) { - for (auto it : rclPAry) + for (auto it : rclPAry) { _clBoundBox.Add(it); + } this->_aclPointArray.insert(this->_aclPointArray.end(), rclPAry.begin(), rclPAry.end()); return this->AddFacets(rclFAry, checkManifolds); } @@ -344,15 +359,16 @@ void MeshKernel::Merge(const MeshKernel& rKernel) { if (this != &rKernel) { const MeshPointArray& rPoints = rKernel._aclPointArray; - const MeshFacetArray& rFacets = rKernel._aclFacetArray; + const MeshFacetArray& rFacets = rKernel._aclFacetArray; Merge(rPoints, rFacets); } } void MeshKernel::Merge(const MeshPointArray& rPoints, const MeshFacetArray& rFaces) { - if (rPoints.empty() || rFaces.empty()) - return; // nothing to do + if (rPoints.empty() || rFaces.empty()) { + return; // nothing to do + } std::vector increments(rPoints.size()); FacetIndex countFacets = this->_aclFacetArray.size(); @@ -361,7 +377,7 @@ void MeshKernel::Merge(const MeshPointArray& rPoints, const MeshFacetArray& rFac // Copy the new faces immediately to the facet array MeshFacet face; - for(const auto & it : rFaces) { + for (const auto& it : rFaces) { face = it; for (PointIndex point : it._aulPoints) { increments[point]++; @@ -371,9 +387,10 @@ void MeshKernel::Merge(const MeshPointArray& rPoints, const MeshFacetArray& rFac this->_aclFacetArray.push_back(face); } - std::size_t countNewPoints = std::count_if(increments.begin(), increments.end(),[](PointIndex v) { - return v > 0; - }); + std::size_t countNewPoints = + std::count_if(increments.begin(), increments.end(), [](PointIndex v) { + return v > 0; + }); // Reserve the additional memory to append the new points PointIndex index = this->_aclPointArray.size(); this->_aclPointArray.reserve(this->_aclPointArray.size() + countNewPoints); @@ -383,14 +400,15 @@ void MeshKernel::Merge(const MeshPointArray& rPoints, const MeshFacetArray& rFac if (*it > 0) { // set the index of the point array *it = index++; - const MeshPoint& rPt = rPoints[it-increments.begin()]; + const MeshPoint& rPt = rPoints[it - increments.begin()]; this->_aclPointArray.push_back(rPt); _clBoundBox.Add(rPt); } } - for (MeshFacetArray::_TIterator pF = this->_aclFacetArray.begin()+countFacets; - pF != this->_aclFacetArray.end(); ++pF) { + for (MeshFacetArray::_TIterator pF = this->_aclFacetArray.begin() + countFacets; + pF != this->_aclFacetArray.end(); + ++pF) { for (PointIndex& index : pF->_aulPoints) { index = increments[index]; } @@ -409,7 +427,7 @@ void MeshKernel::Cleanup() meshCleanup.RemoveInvalids(); } -void MeshKernel::Clear () +void MeshKernel::Clear() { _aclPointArray.clear(); _aclFacetArray.clear(); @@ -421,12 +439,13 @@ void MeshKernel::Clear () _clBoundBox.SetVoid(); } -bool MeshKernel::DeleteFacet (const MeshFacetIterator &rclIter) +bool MeshKernel::DeleteFacet(const MeshFacetIterator& rclIter) { FacetIndex ulNFacet, ulInd; - if (rclIter._clIter >= _aclFacetArray.end()) + if (rclIter._clIter >= _aclFacetArray.end()) { return false; + } // index of the facet to delete ulInd = rclIter._clIter - _aclFacetArray.begin(); @@ -446,10 +465,10 @@ bool MeshKernel::DeleteFacet (const MeshFacetIterator &rclIter) // erase corner point if needed for (int i = 0; i < 3; i++) { - if ((rclIter._clIter->_aulNeighbours[i] == FACET_INDEX_MAX) && - (rclIter._clIter->_aulNeighbours[(i+1)%3] == FACET_INDEX_MAX)) { + if ((rclIter._clIter->_aulNeighbours[i] == FACET_INDEX_MAX) + && (rclIter._clIter->_aulNeighbours[(i + 1) % 3] == FACET_INDEX_MAX)) { // no neighbours, possibly delete point - ErasePoint(rclIter._clIter->_aulPoints[(i+1)%3], ulInd); + ErasePoint(rclIter._clIter->_aulPoints[(i + 1) % 3], ulInd); } } @@ -459,10 +478,11 @@ bool MeshKernel::DeleteFacet (const MeshFacetIterator &rclIter) return true; } -bool MeshKernel::DeleteFacet (FacetIndex ulInd) +bool MeshKernel::DeleteFacet(FacetIndex ulInd) { - if (ulInd >= _aclFacetArray.size()) + if (ulInd >= _aclFacetArray.size()) { return false; + } MeshFacetIterator clIter(*this); clIter.Set(ulInd); @@ -470,12 +490,12 @@ bool MeshKernel::DeleteFacet (FacetIndex ulInd) return DeleteFacet(clIter); } -void MeshKernel::DeleteFacets (const std::vector &raulFacets) +void MeshKernel::DeleteFacets(const std::vector& raulFacets) { _aclPointArray.SetProperty(0); // number of referencing facets per point - for (const auto & pF : _aclFacetArray) { + for (const auto& pF : _aclFacetArray) { _aclPointArray[pF._aulPoints[0]]._ulProp++; _aclPointArray[pF._aulPoints[1]]._ulProp++; _aclPointArray[pF._aulPoints[2]]._ulProp++; @@ -484,7 +504,7 @@ void MeshKernel::DeleteFacets (const std::vector &raulFacets) // invalidate facet and adjust number of point references _aclFacetArray.ResetInvalid(); for (FacetIndex index : raulFacets) { - MeshFacet &rclFacet = _aclFacetArray[index]; + MeshFacet& rclFacet = _aclFacetArray[index]; rclFacet.SetInvalid(); _aclPointArray[rclFacet._aulPoints[0]]._ulProp--; _aclPointArray[rclFacet._aulPoints[1]]._ulProp--; @@ -493,19 +513,21 @@ void MeshKernel::DeleteFacets (const std::vector &raulFacets) // invalidate all unreferenced points _aclPointArray.ResetInvalid(); - for (auto & pP : _aclPointArray) { - if (pP._ulProp == 0) + for (auto& pP : _aclPointArray) { + if (pP._ulProp == 0) { pP.SetInvalid(); + } } RemoveInvalids(); RecalcBoundBox(); } -bool MeshKernel::DeletePoint (PointIndex ulInd) +bool MeshKernel::DeletePoint(PointIndex ulInd) { - if (ulInd >= _aclPointArray.size()) + if (ulInd >= _aclPointArray.size()) { return false; + } MeshPointIterator clIter(*this); clIter.Set(ulInd); @@ -513,10 +535,10 @@ bool MeshKernel::DeletePoint (PointIndex ulInd) return DeletePoint(clIter); } -bool MeshKernel::DeletePoint (const MeshPointIterator &rclIter) +bool MeshKernel::DeletePoint(const MeshPointIterator& rclIter) { MeshFacetIterator pFIter(*this), pFEnd(*this); - std::vector clToDel; + std::vector clToDel; PointIndex ulInd; // index of the point to delete @@ -528,8 +550,9 @@ bool MeshKernel::DeletePoint (const MeshPointIterator &rclIter) // check corner points of all facets while (pFIter < pFEnd) { for (PointIndex ptIndex : pFIter._clIter->_aulPoints) { - if (ulInd == ptIndex) + if (ulInd == ptIndex) { clToDel.push_back(pFIter); + } } ++pFIter; } @@ -539,23 +562,25 @@ bool MeshKernel::DeletePoint (const MeshPointIterator &rclIter) // delete each facet separately (from back to front to avoid to // invalidate the iterators) - for (size_t i = clToDel.size(); i > 0; i--) - DeleteFacet(clToDel[i-1]); + for (size_t i = clToDel.size(); i > 0; i--) { + DeleteFacet(clToDel[i - 1]); + } return true; } -void MeshKernel::DeletePoints (const std::vector &raulPoints) +void MeshKernel::DeletePoints(const std::vector& raulPoints) { _aclPointArray.ResetInvalid(); - for (PointIndex ptIndex : raulPoints) + for (PointIndex ptIndex : raulPoints) { _aclPointArray[ptIndex].SetInvalid(); + } // delete facets if at least one corner point is invalid _aclPointArray.SetProperty(0); - for (auto & pF : _aclFacetArray) { - MeshPoint &rclP0 = _aclPointArray[pF._aulPoints[0]]; - MeshPoint &rclP1 = _aclPointArray[pF._aulPoints[1]]; - MeshPoint &rclP2 = _aclPointArray[pF._aulPoints[2]]; + for (auto& pF : _aclFacetArray) { + MeshPoint& rclP0 = _aclPointArray[pF._aulPoints[0]]; + MeshPoint& rclP1 = _aclPointArray[pF._aulPoints[1]]; + MeshPoint& rclP2 = _aclPointArray[pF._aulPoints[2]]; if (!rclP0.IsValid() || !rclP1.IsValid() || !rclP2.IsValid()) { pF.SetInvalid(); @@ -569,28 +594,30 @@ void MeshKernel::DeletePoints (const std::vector &raulPoints) } // invalidate all unreferenced points to delete them - for (auto & pP : _aclPointArray) { - if (pP._ulProp == 0) + for (auto& pP : _aclPointArray) { + if (pP._ulProp == 0) { pP.SetInvalid(); + } } RemoveInvalids(); RecalcBoundBox(); } -void MeshKernel::ErasePoint (PointIndex ulIndex, FacetIndex ulFacetIndex, bool bOnlySetInvalid) +void MeshKernel::ErasePoint(PointIndex ulIndex, FacetIndex ulFacetIndex, bool bOnlySetInvalid) { std::vector::iterator pFIter, pFEnd, pFNot; pFIter = _aclFacetArray.begin(); - pFNot = _aclFacetArray.begin() + ulFacetIndex; - pFEnd = _aclFacetArray.end(); + pFNot = _aclFacetArray.begin() + ulFacetIndex; + pFEnd = _aclFacetArray.end(); // check all facets while (pFIter < pFNot) { for (PointIndex ptIndex : pFIter->_aulPoints) { - if (ptIndex == ulIndex) - return; // point still referenced ==> do not delete + if (ptIndex == ulIndex) { + return; // point still referenced ==> do not delete + } } ++pFIter; } @@ -598,8 +625,9 @@ void MeshKernel::ErasePoint (PointIndex ulIndex, FacetIndex ulFacetIndex, bool b ++pFIter; while (pFIter < pFEnd) { for (PointIndex ptIndex : pFIter->_aulPoints) { - if (ptIndex == ulIndex) - return; // point still referenced ==> do not delete + if (ptIndex == ulIndex) { + return; // point still referenced ==> do not delete + } } ++pFIter; } @@ -612,18 +640,20 @@ void MeshKernel::ErasePoint (PointIndex ulIndex, FacetIndex ulFacetIndex, bool b // correct point indices of the facets pFIter = _aclFacetArray.begin(); while (pFIter < pFEnd) { - for (PointIndex & ptIndex : pFIter->_aulPoints) { - if (ptIndex > ulIndex) + for (PointIndex& ptIndex : pFIter->_aulPoints) { + if (ptIndex > ulIndex) { ptIndex--; + } } ++pFIter; } } - else // only invalidate + else { // only invalidate _aclPointArray[ulIndex].SetInvalid(); + } } -void MeshKernel::RemoveInvalids () +void MeshKernel::RemoveInvalids() { std::vector aulDecrements; std::vector::iterator pDIter; @@ -634,16 +664,17 @@ void MeshKernel::RemoveInvalids () // generate array of decrements aulDecrements.resize(_aclPointArray.size()); pDIter = aulDecrements.begin(); - ulDec = 0; - pPEnd = _aclPointArray.end(); + ulDec = 0; + pPEnd = _aclPointArray.end(); for (pPIter = _aclPointArray.begin(); pPIter != pPEnd; ++pPIter) { *pDIter++ = ulDec; - if (!pPIter->IsValid()) + if (!pPIter->IsValid()) { ulDec++; + } } // correct point indices of the facets - pFEnd = _aclFacetArray.end(); + pFEnd = _aclFacetArray.end(); for (pFIter = _aclFacetArray.begin(); pFIter != pFEnd; ++pFIter) { if (pFIter->IsValid()) { pFIter->_aulPoints[0] -= aulDecrements[pFIter->_aulPoints[0]]; @@ -653,59 +684,68 @@ void MeshKernel::RemoveInvalids () } // delete point, number of valid points - unsigned long ulNewPts = std::count_if(_aclPointArray.begin(), _aclPointArray.end(), - [](const MeshPoint& p) { return p.IsValid(); }); + unsigned long ulNewPts = + std::count_if(_aclPointArray.begin(), _aclPointArray.end(), [](const MeshPoint& p) { + return p.IsValid(); + }); // tmp. point array - MeshPointArray aclTempPt(ulNewPts); + MeshPointArray aclTempPt(ulNewPts); MeshPointArray::_TIterator pPTemp = aclTempPt.begin(); pPEnd = _aclPointArray.end(); for (pPIter = _aclPointArray.begin(); pPIter != pPEnd; ++pPIter) { - if (pPIter->IsValid()) + if (pPIter->IsValid()) { *pPTemp++ = *pPIter; + } } // free memory //_aclPointArray = aclTempPt; - //aclTempPt.clear(); + // aclTempPt.clear(); _aclPointArray.swap(aclTempPt); MeshPointArray().swap(aclTempPt); // generate array of facet decrements aulDecrements.resize(_aclFacetArray.size()); pDIter = aulDecrements.begin(); - ulDec = 0; - pFEnd = _aclFacetArray.end(); + ulDec = 0; + pFEnd = _aclFacetArray.end(); for (pFIter = _aclFacetArray.begin(); pFIter != pFEnd; ++pFIter, ++pDIter) { *pDIter = ulDec; - if (!pFIter->IsValid()) + if (!pFIter->IsValid()) { ulDec++; + } } // correct neighbour indices of the facets pFEnd = _aclFacetArray.end(); for (pFIter = _aclFacetArray.begin(); pFIter != pFEnd; ++pFIter) { if (pFIter->IsValid()) { - for (FacetIndex & nbIndex : pFIter->_aulNeighbours) { + for (FacetIndex& nbIndex : pFIter->_aulNeighbours) { FacetIndex k = nbIndex; if (k != FACET_INDEX_MAX) { - if (_aclFacetArray[k].IsValid()) + if (_aclFacetArray[k].IsValid()) { nbIndex -= aulDecrements[k]; - else + } + else { nbIndex = FACET_INDEX_MAX; + } } } } } // delete facets, number of valid facets - unsigned long ulDelFacets = std::count_if(_aclFacetArray.begin(), _aclFacetArray.end(), - [](const MeshFacet& f) { return f.IsValid(); }); + unsigned long ulDelFacets = + std::count_if(_aclFacetArray.begin(), _aclFacetArray.end(), [](const MeshFacet& f) { + return f.IsValid(); + }); MeshFacetArray aclFArray(ulDelFacets); MeshFacetArray::_TIterator pFTemp = aclFArray.begin(); - pFEnd = _aclFacetArray.end(); + pFEnd = _aclFacetArray.end(); for (pFIter = _aclFacetArray.begin(); pFIter != pFEnd; ++pFIter) { - if (pFIter->IsValid()) + if (pFIter->IsValid()) { *pFTemp++ = *pFIter; + } } // free memory @@ -713,21 +753,28 @@ void MeshKernel::RemoveInvalids () _aclFacetArray.swap(aclFArray); } -void MeshKernel::CutFacets(const MeshFacetGrid& rclGrid, const Base::ViewProjMethod* pclProj, - const Base::Polygon2d& rclPoly, bool bCutInner, std::vector &raclFacets) +void MeshKernel::CutFacets(const MeshFacetGrid& rclGrid, + const Base::ViewProjMethod* pclProj, + const Base::Polygon2d& rclPoly, + bool bCutInner, + std::vector& raclFacets) { std::vector aulFacets; - MeshAlgorithm(*this).CheckFacets(rclGrid, pclProj, rclPoly, bCutInner, aulFacets ); + MeshAlgorithm(*this).CheckFacets(rclGrid, pclProj, rclPoly, bCutInner, aulFacets); - for (FacetIndex it : aulFacets) + for (FacetIndex it : aulFacets) { raclFacets.push_back(GetFacet(it)); + } DeleteFacets(aulFacets); } -void MeshKernel::CutFacets(const MeshFacetGrid& rclGrid, const Base::ViewProjMethod* pclProj, - const Base::Polygon2d& rclPoly, bool bInner, std::vector &raclCutted) +void MeshKernel::CutFacets(const MeshFacetGrid& rclGrid, + const Base::ViewProjMethod* pclProj, + const Base::Polygon2d& rclPoly, + bool bInner, + std::vector& raclCutted) { MeshAlgorithm(*this).CheckFacets(rclGrid, pclProj, rclPoly, bInner, raclCutted); DeleteFacets(raclCutted); @@ -753,18 +800,18 @@ std::vector MeshKernel::GetPointFacets(const std::vector { _aclPointArray.ResetFlag(MeshPoint::TMP0); _aclFacetArray.ResetFlag(MeshFacet::TMP0); - for (PointIndex point : points) + for (PointIndex point : points) { _aclPointArray[point].SetFlag(MeshPoint::TMP0); + } // mark facets if at least one corner point is marked - for (const auto & pF : _aclFacetArray) { - const MeshPoint &rclP0 = _aclPointArray[pF._aulPoints[0]]; - const MeshPoint &rclP1 = _aclPointArray[pF._aulPoints[1]]; - const MeshPoint &rclP2 = _aclPointArray[pF._aulPoints[2]]; + for (const auto& pF : _aclFacetArray) { + const MeshPoint& rclP0 = _aclPointArray[pF._aulPoints[0]]; + const MeshPoint& rclP1 = _aclPointArray[pF._aulPoints[1]]; + const MeshPoint& rclP2 = _aclPointArray[pF._aulPoints[2]]; - if (rclP0.IsFlag(MeshPoint::TMP0) || - rclP1.IsFlag(MeshPoint::TMP0) || - rclP2.IsFlag(MeshPoint::TMP0)) { + if (rclP0.IsFlag(MeshPoint::TMP0) || rclP1.IsFlag(MeshPoint::TMP0) + || rclP2.IsFlag(MeshPoint::TMP0)) { pF.SetFlag(MeshFacet::TMP0); } } @@ -774,15 +821,15 @@ std::vector MeshKernel::GetPointFacets(const std::vector return facets; } -std::vector MeshKernel::HasFacets (const MeshPointIterator &rclIter) const +std::vector MeshKernel::HasFacets(const MeshPointIterator& rclIter) const { PointIndex ulPtInd = rclIter.Position(); - std::vector::const_iterator pFIter = _aclFacetArray.begin(); - std::vector::const_iterator pFBegin = _aclFacetArray.begin(); - std::vector::const_iterator pFEnd = _aclFacetArray.end(); + std::vector::const_iterator pFIter = _aclFacetArray.begin(); + std::vector::const_iterator pFBegin = _aclFacetArray.begin(); + std::vector::const_iterator pFEnd = _aclFacetArray.end(); std::vector aulBelongs; - while (pFIter < pFEnd) { + while (pFIter < pFEnd) { for (PointIndex point : pFIter->_aulPoints) { if (point == ulPtInd) { aulBelongs.push_back(pFIter - pFBegin); @@ -799,8 +846,9 @@ MeshPointArray MeshKernel::GetPoints(const std::vector& indices) con { MeshPointArray ary; ary.reserve(indices.size()); - for (PointIndex it : indices) + for (PointIndex it : indices) { ary.push_back(this->_aclPointArray[it]); + } return ary; } @@ -808,15 +856,17 @@ MeshFacetArray MeshKernel::GetFacets(const std::vector& indices) con { MeshFacetArray ary; ary.reserve(indices.size()); - for (FacetIndex it : indices) + for (FacetIndex it : indices) { ary.push_back(this->_aclFacetArray[it]); + } return ary; } -void MeshKernel::Write (std::ostream &rclOut) const +void MeshKernel::Write(std::ostream& rclOut) const { - if (!rclOut || rclOut.bad()) + if (!rclOut || rclOut.bad()) { return; + } Base::OutputStream str(rclOut); @@ -824,24 +874,24 @@ void MeshKernel::Write (std::ostream &rclOut) const str << static_cast(0xA0B0C0D0); str << static_cast(0x010000); - char szInfo[257]; // needs an additional byte for zero-termination - strcpy(szInfo, "MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-" - "MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-" - "MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-" - "MESH-MESH-MESH-\n"); + char szInfo[257]; // needs an additional byte for zero-termination + strcpy(szInfo, + "MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-" + "MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-" + "MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-MESH-" + "MESH-MESH-MESH-\n"); rclOut.write(szInfo, 256); // write the number of points and facets str << static_cast(CountPoints()) << static_cast(CountFacets()); // write the data - for (const auto & it : _aclPointArray) { + for (const auto& it : _aclPointArray) { str << it.x << it.y << it.z; } - for (const auto & it : _aclFacetArray) { - str << static_cast(it._aulPoints[0]) - << static_cast(it._aulPoints[1]) + for (const auto& it : _aclFacetArray) { + str << static_cast(it._aulPoints[0]) << static_cast(it._aulPoints[1]) << static_cast(it._aulPoints[2]); str << static_cast(it._aulNeighbours[0]) << static_cast(it._aulNeighbours[1]) @@ -853,10 +903,11 @@ void MeshKernel::Write (std::ostream &rclOut) const str << _clBoundBox.MinZ << _clBoundBox.MaxZ; } -void MeshKernel::Read (std::istream &rclIn) +void MeshKernel::Read(std::istream& rclIn) { - if (!rclIn || rclIn.bad()) + if (!rclIn || rclIn.bad()) { return; + } // get header Base::InputStream str(rclIn); @@ -864,9 +915,11 @@ void MeshKernel::Read (std::istream &rclIn) // Read the header with a "magic number" and a version uint32_t magic, version, swap_magic, swap_version; str >> magic >> version; - swap_magic = magic; Base::SwapEndian(swap_magic); - swap_version = version; Base::SwapEndian(swap_version); - uint32_t open_edge = 0xffffffff; // value to mark an open edge + swap_magic = magic; + Base::SwapEndian(swap_magic); + swap_version = version; + Base::SwapEndian(swap_version); + uint32_t open_edge = 0xffffffff; // value to mark an open edge // is it the new or old format? bool new_format = false; @@ -883,14 +936,14 @@ void MeshKernel::Read (std::istream &rclIn) rclIn.read(szInfo, 256); // read the number of points and facets - uint32_t uCtPts=0, uCtFts=0; + uint32_t uCtPts = 0, uCtFts = 0; str >> uCtPts >> uCtFts; try { // read the data MeshPointArray pointArray; pointArray.resize(uCtPts); - for (auto & it : pointArray) { + for (auto& it : pointArray) { str >> it.x >> it.y >> it.z; } @@ -898,12 +951,13 @@ void MeshKernel::Read (std::istream &rclIn) facetArray.resize(uCtFts); uint32_t v1, v2, v3; - for (auto & it : facetArray) { + for (auto& it : facetArray) { str >> v1 >> v2 >> v3; // make sure to have valid indices - if (v1 >= uCtPts || v2 >= uCtPts || v3 >= uCtPts) + if (v1 >= uCtPts || v2 >= uCtPts || v3 >= uCtPts) { throw Base::BadFormatError("Invalid data structure"); + } it._aulPoints[0] = v1; it._aulPoints[1] = v2; @@ -916,27 +970,36 @@ void MeshKernel::Read (std::istream &rclIn) str >> v1 >> v2 >> v3; // make sure to have valid indices - if (v1 >= uCtFts && v1 < open_edge) + if (v1 >= uCtFts && v1 < open_edge) { throw Base::BadFormatError("Invalid data structure"); - if (v2 >= uCtFts && v2 < open_edge) + } + if (v2 >= uCtFts && v2 < open_edge) { throw Base::BadFormatError("Invalid data structure"); - if (v3 >= uCtFts && v3 < open_edge) + } + if (v3 >= uCtFts && v3 < open_edge) { throw Base::BadFormatError("Invalid data structure"); + } - if (v1 < open_edge) + if (v1 < open_edge) { it._aulNeighbours[0] = v1; - else + } + else { it._aulNeighbours[0] = FACET_INDEX_MAX; + } - if (v2 < open_edge) + if (v2 < open_edge) { it._aulNeighbours[1] = v2; - else + } + else { it._aulNeighbours[1] = FACET_INDEX_MAX; + } - if (v3 < open_edge) + if (v3 < open_edge) { it._aulNeighbours[2] = v3; - else + } + else { it._aulNeighbours[2] = FACET_INDEX_MAX; + } } str >> _clBoundBox.MinX >> _clBoundBox.MaxX; @@ -954,7 +1017,7 @@ void MeshKernel::Read (std::istream &rclIn) } else { // The old formats - unsigned long uCtPts=magic, uCtFts=version; + unsigned long uCtPts = magic, uCtFts = version; MeshPointArray pointArray; MeshFacetArray facetArray; @@ -968,30 +1031,30 @@ void MeshKernel::Read (std::istream &rclIn) // the stored mesh kernel might be empty if (uCtPts > 0) { pointArray.resize(uCtPts); - rclIn.read((char*)&(pointArray[0]), uCtPts*sizeof(MeshPoint)); + rclIn.read((char*)&(pointArray[0]), uCtPts * sizeof(MeshPoint)); } if (uCtFts > 0) { facetArray.resize(uCtFts); - rclIn.read((char*)&(facetArray[0]), uCtFts*sizeof(MeshFacet)); + rclIn.read((char*)&(facetArray[0]), uCtFts * sizeof(MeshFacet)); } rclIn.read((char*)&_clBoundBox, sizeof(Base::BoundBox3f)); } else { // with edge array - unsigned long uCtEdges=uCtFts; + unsigned long uCtEdges = uCtFts; str >> magic; uCtFts = magic; pointArray.resize(uCtPts); - for (auto & it : pointArray) { + for (auto& it : pointArray) { str >> it.x >> it.y >> it.z; } uint32_t dummy; - for (unsigned long i=0; i> dummy; } uint32_t v1, v2, v3; facetArray.resize(uCtFts); - for (auto & it : facetArray) { + for (auto& it : facetArray) { str >> v1 >> v2 >> v3; it._aulNeighbours[0] = v1; it._aulNeighbours[1] = v2; @@ -1003,20 +1066,18 @@ void MeshKernel::Read (std::istream &rclIn) str >> it._ucFlag; } - str >> _clBoundBox.MinX - >> _clBoundBox.MinY - >> _clBoundBox.MinZ - >> _clBoundBox.MaxX - >> _clBoundBox.MaxY - >> _clBoundBox.MaxZ; + str >> _clBoundBox.MinX >> _clBoundBox.MinY >> _clBoundBox.MinZ >> _clBoundBox.MaxX + >> _clBoundBox.MaxY >> _clBoundBox.MaxZ; } - for (auto & it : facetArray) { - for (int i=0; i<3; i++) { - if (it._aulPoints[i] >= uCtPts) + for (auto& it : facetArray) { + for (int i = 0; i < 3; i++) { + if (it._aulPoints[i] >= uCtPts) { throw Base::BadFormatError("Invalid data structure"); - if (it._aulNeighbours[i] < FACET_INDEX_MAX && it._aulNeighbours[i] >= uCtFts) + } + if (it._aulNeighbours[i] < FACET_INDEX_MAX && it._aulNeighbours[i] >= uCtFts) { throw Base::BadFormatError("Invalid data structure"); + } } } @@ -1025,14 +1086,14 @@ void MeshKernel::Read (std::istream &rclIn) } } -void MeshKernel::operator *= (const Base::Matrix4D &rclMat) +void MeshKernel::operator*=(const Base::Matrix4D& rclMat) { this->Transform(rclMat); } -void MeshKernel::Transform (const Base::Matrix4D &rclMat) +void MeshKernel::Transform(const Base::Matrix4D& rclMat) { - MeshPointArray::_TIterator clPIter = _aclPointArray.begin(), clPEIter = _aclPointArray.end(); + MeshPointArray::_TIterator clPIter = _aclPointArray.begin(), clPEIter = _aclPointArray.end(); Base::Matrix4D clMatrix(rclMat); _clBoundBox.SetVoid(); @@ -1049,11 +1110,12 @@ void MeshKernel::Smooth(int iterations, float stepsize) LaplaceSmoothing(*this).Smooth(iterations); } -void MeshKernel::RecalcBoundBox () const +void MeshKernel::RecalcBoundBox() const { _clBoundBox.SetVoid(); - for (const auto & pI : _aclPointArray) + for (const auto& pI : _aclPointArray) { _clBoundBox.Add(pI); + } } std::vector MeshKernel::CalcVertexNormals() const @@ -1062,11 +1124,11 @@ std::vector MeshKernel::CalcVertexNormals() const normals.resize(CountPoints()); - PointIndex p1,p2,p3; + PointIndex p1, p2, p3; unsigned int ct = CountFacets(); - for (unsigned int pFIter = 0;pFIter < ct; pFIter++) { - GetFacetPoints(pFIter,p1,p2,p3); - Base::Vector3f Norm = (GetPoint(p2)-GetPoint(p1)) % (GetPoint(p3)-GetPoint(p1)); + for (unsigned int pFIter = 0; pFIter < ct; pFIter++) { + GetFacetPoints(pFIter, p1, p2, p3); + Base::Vector3f Norm = (GetPoint(p2) - GetPoint(p1)) % (GetPoint(p3) - GetPoint(p1)); normals[p1] += Norm; normals[p2] += Norm; @@ -1101,13 +1163,14 @@ float MeshKernel::GetSurface() const { float fSurface = 0.0; MeshFacetIterator cIter(*this); - for (cIter.Init(); cIter.More(); cIter.Next()) + for (cIter.Init(); cIter.More(); cIter.Next()) { fSurface += cIter->Area(); + } return fSurface; } -float MeshKernel::GetSurface( const std::vector& aSegment ) const +float MeshKernel::GetSurface(const std::vector& aSegment) const { float fSurface = 0.0; MeshFacetIterator cIter(*this); @@ -1122,20 +1185,21 @@ float MeshKernel::GetSurface( const std::vector& aSegment ) const float MeshKernel::GetVolume() const { - //MeshEvalSolid cSolid(*this); - //if ( !cSolid.Evaluate() ) - // return 0.0f; // no solid + // MeshEvalSolid cSolid(*this); + // if ( !cSolid.Evaluate() ) + // return 0.0f; // no solid float fVolume = 0.0; MeshFacetIterator cIter(*this); - Base::Vector3f p1,p2,p3; + Base::Vector3f p1, p2, p3; for (cIter.Init(); cIter.More(); cIter.Next()) { const MeshGeomFacet& rclF = *cIter; p1 = rclF._aclPoints[0]; p2 = rclF._aclPoints[1]; p3 = rclF._aclPoints[2]; - fVolume += (-p3.x*p2.y*p1.z + p2.x*p3.y*p1.z + p3.x*p1.y*p2.z - p1.x*p3.y*p2.z - p2.x*p1.y*p3.z + p1.x*p2.y*p3.z); + fVolume += (-p3.x * p2.y * p1.z + p2.x * p3.y * p1.z + p3.x * p1.y * p2.z + - p1.x * p3.y * p2.z - p2.x * p1.y * p3.z + p1.x * p2.y * p3.z); } fVolume /= 6.0f; @@ -1166,27 +1230,31 @@ bool MeshKernel::HasSelfIntersections() const MeshFacetIterator MeshKernel::FacetIterator() const { MeshFacetIterator it(*this); - it.Begin(); return it; + it.Begin(); + return it; } MeshPointIterator MeshKernel::PointIterator() const { MeshPointIterator it(*this); - it.Begin(); return it; + it.Begin(); + return it; } -void MeshKernel::GetEdges (std::vector& edges) const +void MeshKernel::GetEdges(std::vector& edges) const { std::set tmp; - for (const auto & it : _aclFacetArray) { + for (const auto& it : _aclFacetArray) { for (int i = 0; i < 3; i++) { - tmp.insert(MeshBuilder::Edge(it._aulPoints[i], it._aulPoints[(i+1)%3], it._aulNeighbours[i])); + tmp.insert(MeshBuilder::Edge(it._aulPoints[i], + it._aulPoints[(i + 1) % 3], + it._aulNeighbours[i])); } } edges.reserve(tmp.size()); - for (const auto & it2 : tmp) { + for (const auto& it2 : tmp) { MeshGeomEdge edge; edge._aclPoints[0] = this->_aclPointArray[it2.pt1]; edge._aclPoints[1] = this->_aclPointArray[it2.pt2]; @@ -1196,19 +1264,20 @@ void MeshKernel::GetEdges (std::vector& edges) const } } -unsigned long MeshKernel::CountEdges () const +unsigned long MeshKernel::CountEdges() const { unsigned long openEdges = 0, closedEdges = 0; - for (const auto & it : _aclFacetArray) { + for (const auto& it : _aclFacetArray) { for (FacetIndex nbFacet : it._aulNeighbours) { - if (nbFacet == FACET_INDEX_MAX) + if (nbFacet == FACET_INDEX_MAX) { openEdges++; - else + } + else { closedEdges++; + } } } return (openEdges + (closedEdges / 2)); } - diff --git a/src/Mod/Mesh/App/Core/MeshKernel.h b/src/Mod/Mesh/App/Core/MeshKernel.h index d2b1322856..390a1cf01d 100644 --- a/src/Mod/Mesh/App/Core/MeshKernel.h +++ b/src/Mod/Mesh/App/Core/MeshKernel.h @@ -32,12 +32,14 @@ #include "Helpers.h" -namespace Base{ - class Polygon2d; - class ViewProjMethod; -} +namespace Base +{ +class Polygon2d; +class ViewProjMethod; +} // namespace Base -namespace MeshCore { +namespace MeshCore +{ // forward declarations class MeshFacetIterator; @@ -63,48 +65,58 @@ class MeshExport MeshKernel { public: /// Construction - MeshKernel (); + MeshKernel(); /// Construction - MeshKernel (const MeshKernel &rclMesh); + MeshKernel(const MeshKernel& rclMesh); /// Destruction - ~MeshKernel () - { Clear(); } + ~MeshKernel() + { + Clear(); + } /** @name I/O methods */ //@{ /// Binary streaming of data - void Write (std::ostream &rclOut) const; - void Read (std::istream &rclIn); + void Write(std::ostream& rclOut) const; + void Read(std::istream& rclIn); //@} /** @name Querying */ //@{ /// Returns the number of facets - unsigned long CountFacets () const - { return static_cast(_aclFacetArray.size()); } + unsigned long CountFacets() const + { + return static_cast(_aclFacetArray.size()); + } /// Returns the number of edge - unsigned long CountEdges () const; + unsigned long CountEdges() const; // Returns the number of points - unsigned long CountPoints () const - { return static_cast(_aclPointArray.size()); } + unsigned long CountPoints() const + { + return static_cast(_aclPointArray.size()); + } /// Returns the number of required memory in bytes - unsigned int GetMemSize () const - { return static_cast(_aclPointArray.size() * sizeof(MeshPoint) + - _aclFacetArray.size() * sizeof(MeshFacet)); } + unsigned int GetMemSize() const + { + return static_cast(_aclPointArray.size() * sizeof(MeshPoint) + + _aclFacetArray.size() * sizeof(MeshFacet)); + } /// Determines the bounding box - const Base::BoundBox3f& GetBoundBox () const - { return _clBoundBox; } + const Base::BoundBox3f& GetBoundBox() const + { + return _clBoundBox; + } /** Forces a recalculation of the bounding box. This method should be called after * the removal of points.or after a transformation of the data structure. */ - void RecalcBoundBox () const; + void RecalcBoundBox() const; /** Returns the point at the given index. This method is rather slow and should be * called occasionally only. For fast access the MeshPointIterator interfsce should * be used. */ - inline MeshPoint GetPoint (PointIndex ulIndex) const; + inline MeshPoint GetPoint(PointIndex ulIndex) const; /** Returns an array of the vertex normals of the mesh. A vertex normal gets calculated * by summarizing the normals of the associated facets. @@ -116,34 +128,43 @@ public: * called occasionally only. For fast access the MeshFacetIterator interface should * be used. */ - inline MeshGeomFacet GetFacet (FacetIndex ulIndex) const; - inline MeshGeomFacet GetFacet (const MeshFacet &rclFacet) const; + inline MeshGeomFacet GetFacet(FacetIndex ulIndex) const; + inline MeshGeomFacet GetFacet(const MeshFacet& rclFacet) const; /** Returns the point indices of the given facet index. */ - inline void GetFacetPoints (FacetIndex ulFaIndex, PointIndex &rclP0, - PointIndex &rclP1, PointIndex &rclP2) const; + inline void GetFacetPoints(FacetIndex ulFaIndex, + PointIndex& rclP0, + PointIndex& rclP1, + PointIndex& rclP2) const; /** Returns the point indices of the given facet index. */ - inline void SetFacetPoints (FacetIndex ulFaIndex, PointIndex rclP0, - PointIndex rclP1, PointIndex rclP2); + inline void + SetFacetPoints(FacetIndex ulFaIndex, PointIndex rclP0, PointIndex rclP1, PointIndex rclP2); /** Returns the point indices of the given facet indices. */ std::vector GetFacetPoints(const std::vector&) const; /** Returns the facet indices that share the given point indices. */ std::vector GetPointFacets(const std::vector&) const; /** Returns the indices of the neighbour facets of the given facet index. */ - inline void GetFacetNeighbours (FacetIndex ulIndex, FacetIndex &rulNIdx0, - FacetIndex &rulNIdx1, FacetIndex &rulNIdx2) const; + inline void GetFacetNeighbours(FacetIndex ulIndex, + FacetIndex& rulNIdx0, + FacetIndex& rulNIdx1, + FacetIndex& rulNIdx2) const; /** Determines all facets that are associated to this point. This method is very * slow and should be called occasionally only. */ - std::vector HasFacets (const MeshPointIterator &rclIter) const; + std::vector HasFacets(const MeshPointIterator& rclIter) const; /** Returns true if the data structure is valid. */ - bool IsValid () const - { return _bValid; } + bool IsValid() const + { + return _bValid; + } /** Returns the array of all data points. */ - const MeshPointArray& GetPoints () const { return _aclPointArray; } + const MeshPointArray& GetPoints() const + { + return _aclPointArray; + } /** Returns an array of points to the given indices. The indices * must not be out of range. */ @@ -156,7 +177,10 @@ public: } /** Returns the array of all facets */ - const MeshFacetArray& GetFacets () const { return _aclFacetArray; } + const MeshFacetArray& GetFacets() const + { + return _aclFacetArray; + } /** Returns an array of facets to the given indices. The indices * must not be out of range. */ @@ -172,7 +196,7 @@ public: * Notice: The Edgelist will be temporary generated. Changes on the mesh * structure does not affect the Edgelist */ - void GetEdges (std::vector&) const; + void GetEdges(std::vector&) const; //@} /** @name Evaluation */ @@ -180,11 +204,11 @@ public: /** Calculates the surface area of the mesh object. */ float GetSurface() const; /** Calculates the surface area of the segment defined by \a aSegment. */ - float GetSurface( const std::vector& aSegment ) const; + float GetSurface(const std::vector& aSegment) const; /** Calculates the volume of the mesh object. Therefore the mesh must be a solid, if not 0 * is returned. */ - float GetVolume () const; + float GetVolume() const; /** Checks whether the mesh has open edges. */ bool HasOpenEdges() const; /** Checks whether the mesh has non.manifold edges. An edge is regarded as non-manifolds if it @@ -214,15 +238,17 @@ public: * of the given MeshFacetVisitor gets invoked. * If there are no unvisited neighbours any more the algorithms returns immediately and returns * the number of visited facets. - * \note For the start facet \a ulStartFacet MeshFacetVisitor::Visit() does not get invoked though - * the facet gets marked as VISIT. + * \note For the start facet \a ulStartFacet MeshFacetVisitor::Visit() does not get invoked + * though the facet gets marked as VISIT. */ - unsigned long VisitNeighbourFacets (MeshFacetVisitor &rclFVisitor, FacetIndex ulStartFacet) const; + unsigned long VisitNeighbourFacets(MeshFacetVisitor& rclFVisitor, + FacetIndex ulStartFacet) const; /** * Does basically the same as the method above unless the facets that share just a common point * are regared as neighbours. */ - unsigned long VisitNeighbourFacetsOverCorners (MeshFacetVisitor &rclFVisitor, FacetIndex ulStartFacet) const; + unsigned long VisitNeighbourFacetsOverCorners(MeshFacetVisitor& rclFVisitor, + FacetIndex ulStartFacet) const; //@} /** @name Point visitors @@ -234,17 +260,17 @@ public: */ //@{ /** - * This method visits all neighbour points starting from the point associated to index \a ulStartPoint. - * All points having set the VISIT flag are ignored. Therefore the user have to set or unset this flag - * if needed before the algorithm starts. - * All points that get visited during this algorithm are marked as VISIT and the Visit() method - * of the given MeshPointVisitor gets invoked. - * If there are no unvisited neighbours any more the algorithms returns immediately and returns - * the number of visited points. - * \note For the start facet \a ulStartPoint MeshPointVisitor::Visit() does not get invoked though - * the point gets marked as VISIT. + * This method visits all neighbour points starting from the point associated to index \a + * ulStartPoint. All points having set the VISIT flag are ignored. Therefore the user have to + * set or unset this flag if needed before the algorithm starts. All points that get visited + * during this algorithm are marked as VISIT and the Visit() method of the given + * MeshPointVisitor gets invoked. If there are no unvisited neighbours any more the algorithms + * returns immediately and returns the number of visited points. \note For the start facet \a + * ulStartPoint MeshPointVisitor::Visit() does not get invoked though the point gets marked as + * VISIT. */ - unsigned long VisitNeighbourPoints (MeshPointVisitor &rclPVisitor, PointIndex ulStartPoint) const; + unsigned long VisitNeighbourPoints(MeshPointVisitor& rclPVisitor, + PointIndex ulStartPoint) const; //@} /** @name Iterators @@ -277,19 +303,19 @@ public: /** Adds a single facet to the data structure. This method is very slow and should * be called occasionally only. */ - MeshKernel& operator += (const MeshGeomFacet &rclSFacet); + MeshKernel& operator+=(const MeshGeomFacet& rclSFacet); /** Adds a single facet to the data structure. This method is very slow and should * be called occasionally only. This does the same as the += operator above. */ - void AddFacet(const MeshGeomFacet &rclSFacet); + void AddFacet(const MeshGeomFacet& rclSFacet); /** Adds an array of facets to the data structure. This method keeps temporarily * set properties and flags. */ - MeshKernel& operator += (const std::vector &rclFAry); + MeshKernel& operator+=(const std::vector& rclFAry); /** Adds an array of facets to the data structure. This method keeps temporarily * set properties and flags. This does the same as the += operator above. */ - void AddFacets(const std::vector &rclFAry); + void AddFacets(const std::vector& rclFAry); /** * Adds an array of topologic facets to the data structure without inserting new points. * Facets which would create non-manifolds are not inserted. @@ -298,13 +324,13 @@ public: * This method might be useful to close gaps or fill up holes in a mesh. * @note This method is quite expensive and should be rarely used. */ - unsigned long AddFacets(const std::vector &rclFAry, bool checkManifolds); + unsigned long AddFacets(const std::vector& rclFAry, bool checkManifolds); /** * Adds new points and facets to the data structure. The client programmer must make sure * that all new points are referenced by the new facets. - * All points in \a rclPAry get copied at the end of the internal point array to keep their order. - * The point indices of the facets must be related to the internal point array, not the passed - * array \a rclPAry. + * All points in \a rclPAry get copied at the end of the internal point array to keep their + * order. The point indices of the facets must be related to the internal point array, not the + * passed array \a rclPAry. * * Example: * We have a mesh with p points and f facets where we want append new points and facets to. @@ -313,17 +339,17 @@ public: * that facets of \a rclFAry can also reference point indices of the internal point array. * @note This method is quite expensive and should be rarely used. */ - unsigned long AddFacets(const std::vector &rclFAry, + unsigned long AddFacets(const std::vector& rclFAry, const std::vector& rclPAry, bool checkManifolds); /** * Adds all facets and referenced points to the underlying mesh structure. The client programmer - * must be sure that both meshes don't have geometric overlaps, otherwise the resulting mesh might - * be invalid, i.e. has self-intersections. - * @note The method guarantees that the order of the arrays of the underlying mesh and of the given - * array is kept. - * @note Not all points of \a rKernel are necessarily appended to the underlying mesh but only these - * points which are referenced by facets of \a rKernel. + * must be sure that both meshes don't have geometric overlaps, otherwise the resulting mesh + * might be invalid, i.e. has self-intersections. + * @note The method guarantees that the order of the arrays of the underlying mesh and of the + * given array is kept. + * @note Not all points of \a rKernel are necessarily appended to the underlying mesh but only + * these points which are referenced by facets of \a rKernel. */ void Merge(const MeshKernel& rKernel); /** @@ -343,112 +369,120 @@ public: * @note After deletion of the facet \a rclIter becomes invalid and must not * be used before setting to a new position. */ - bool DeleteFacet (const MeshFacetIterator &rclIter); + bool DeleteFacet(const MeshFacetIterator& rclIter); /** * Does basically the same as the method above unless that the index of the facet is given. */ - bool DeleteFacet (FacetIndex ulInd); + bool DeleteFacet(FacetIndex ulInd); /** Removes several facets from the data structure. * @note This method overwrites the free usable property of each mesh point. * @note This method also removes points from the structure that are no longer * referenced by the facets. * @note This method is very slow and should only be called occasionally. */ - void DeleteFacets (const std::vector &raulFacets); - /** Deletes the point the iterator points to. The deletion of a point requires the following step: - * \li Find all associated facets to this point. - * \li Delete these facets. - * True is returned if the point could be deleted. + void DeleteFacets(const std::vector& raulFacets); + /** Deletes the point the iterator points to. The deletion of a point requires the following + * step: \li Find all associated facets to this point. \li Delete these facets. True is returned + * if the point could be deleted. * @note This method is very slow and should only be called occasionally. * @note After deletion of the point \a rclIter becomes invalid and must not * be used before setting to a new position. */ - bool DeletePoint (const MeshPointIterator &rclIter); + bool DeletePoint(const MeshPointIterator& rclIter); /** * Does basically the same as the method above unless that the index of the facet is given. */ - bool DeletePoint (PointIndex ulInd); + bool DeletePoint(PointIndex ulInd); /** Removes several points from the data structure. * @note This method overwrites the free usable property of each mesh point. */ - void DeletePoints (const std::vector &raulPoints); + void DeletePoints(const std::vector& raulPoints); /** Removes all as INVALID marked points and facets from the structure. */ - void RemoveInvalids (); + void RemoveInvalids(); /** Rebuilds the neighbour indices for all facets. */ - void RebuildNeighbours (); + void RebuildNeighbours(); /** Removes unreferenced points or facets with invalid indices from the mesh. */ void Cleanup(); /** Clears the whole data structure. */ - void Clear (); + void Clear(); /** Replaces the current data structure with the structure built up of the array * of triangles given in \a rclFAry. */ - MeshKernel& operator = (const std::vector &rclFAry); + MeshKernel& operator=(const std::vector& rclFAry); /** Assignment operator. */ - MeshKernel& operator = (const MeshKernel &rclMesh); - /** This allows to assign the mesh structure directly. The caller must make sure that the point indices are - * correctly set but the neighbourhood gets checked and corrected if \a checkNeighbourHood is true. + MeshKernel& operator=(const MeshKernel& rclMesh); + /** This allows to assign the mesh structure directly. The caller must make sure that the point + * indices are correctly set but the neighbourhood gets checked and corrected if \a + * checkNeighbourHood is true. */ - void Assign(const MeshPointArray& rPoints, const MeshFacetArray& rFaces, bool checkNeighbourHood=false); - /** This method does basically the same as Assign() unless that it swaps the content of both arrays. - * These arrays may be empty after assigning to the kernel. This method is a convenient way to build up - * the mesh structure from outside and assign to a mesh kernel without copying the data. - * Especially for huge meshes this saves memory and increases speed. + void Assign(const MeshPointArray& rPoints, + const MeshFacetArray& rFaces, + bool checkNeighbourHood = false); + /** This method does basically the same as Assign() unless that it swaps the content of both + * arrays. These arrays may be empty after assigning to the kernel. This method is a convenient + * way to build up the mesh structure from outside and assign to a mesh kernel without copying + * the data. Especially for huge meshes this saves memory and increases speed. */ - void Adopt(MeshPointArray& rPoints, MeshFacetArray& rFaces, bool checkNeighbourHood=false); + void Adopt(MeshPointArray& rPoints, MeshFacetArray& rFaces, bool checkNeighbourHood = false); /// Swaps the content of this kernel and \a mesh void Swap(MeshKernel& mesh); /// Transform the data structure with the given transformation matrix. - void operator *= (const Base::Matrix4D &rclMat); + void operator*=(const Base::Matrix4D& rclMat); /** Transform the data structure with the given transformation matrix. * It does exactly the same as the '*=' operator. */ - void Transform (const Base::Matrix4D &rclMat); + void Transform(const Base::Matrix4D& rclMat); /** Moves the point at the given index along the vector \a rclTrans. */ - inline void MovePoint (PointIndex ulPtIndex, const Base::Vector3f &rclTrans); + inline void MovePoint(PointIndex ulPtIndex, const Base::Vector3f& rclTrans); /** Sets the point at the given index to the new \a rPoint. */ - inline void SetPoint (PointIndex ulPtIndex, const Base::Vector3f &rPoint); + inline void SetPoint(PointIndex ulPtIndex, const Base::Vector3f& rPoint); /** Sets the point at the given index to the new \a rPoint. */ - inline void SetPoint (PointIndex ulPtIndex, float x, float y, float z); + inline void SetPoint(PointIndex ulPtIndex, float x, float y, float z); /** Smoothes the mesh kernel. */ void Smooth(int iterations, float d_max); /** - * CheckFacets() is invoked within this method and all found facets get deleted from the mesh structure. - * The facets to be deleted are returned with their geometric representation. + * CheckFacets() is invoked within this method and all found facets get deleted from the mesh + * structure. The facets to be deleted are returned with their geometric representation. * @see CheckFacets(). */ - void CutFacets (const MeshFacetGrid& rclGrid, const Base::ViewProjMethod *pclP, const Base::Polygon2d& rclPoly, - bool bCutInner, std::vector &raclFacets); + void CutFacets(const MeshFacetGrid& rclGrid, + const Base::ViewProjMethod* pclP, + const Base::Polygon2d& rclPoly, + bool bCutInner, + std::vector& raclFacets); /** - * Does basically the same as method above unless that the facets to be deleted are returned with their - * index number in the facet array of the mesh structure. + * Does basically the same as method above unless that the facets to be deleted are returned + * with their index number in the facet array of the mesh structure. */ - void CutFacets (const MeshFacetGrid& rclGrid, const Base::ViewProjMethod* pclP, const Base::Polygon2d& rclPoly, - bool bCutInner, std::vector &raclCutted); + void CutFacets(const MeshFacetGrid& rclGrid, + const Base::ViewProjMethod* pclP, + const Base::Polygon2d& rclPoly, + bool bCutInner, + std::vector& raclCutted); //@} protected: /** Rebuilds the neighbour indices for subset of all facets from index \a index on. */ - void RebuildNeighbours (FacetIndex); + void RebuildNeighbours(FacetIndex); /** Checks if this point is associated to no other facet and deletes if so. * The point indices of the facets get adjusted. * \a ulIndex is the index of the point to be deleted. \a ulFacetIndex is the index * of the quasi deleted facet and is ignored. If \a bOnlySetInvalid is true the point * doesn't get deleted but marked as invalid. */ - void ErasePoint (PointIndex ulIndex, FacetIndex ulFacetIndex, bool bOnlySetInvalid = false); + void ErasePoint(PointIndex ulIndex, FacetIndex ulFacetIndex, bool bOnlySetInvalid = false); /** Adjusts the facet's orierntation to the given normal direction. */ - inline void AdjustNormal (MeshFacet &rclFacet, const Base::Vector3f &rclNormal); + inline void AdjustNormal(MeshFacet& rclFacet, const Base::Vector3f& rclNormal); /** Calculates the normal to the given facet. */ - inline Base::Vector3f GetNormal (const MeshFacet &rclFacet) const; + inline Base::Vector3f GetNormal(const MeshFacet& rclFacet) const; /** Calculates the gravity point to the given facet. */ - inline Base::Vector3f GetGravityPoint (const MeshFacet &rclFacet) const; + inline Base::Vector3f GetGravityPoint(const MeshFacet& rclFacet) const; - MeshPointArray _aclPointArray; /**< Holds the array of geometric points. */ - MeshFacetArray _aclFacetArray; /**< Holds the array of facets. */ - mutable Base::BoundBox3f _clBoundBox; /**< The current calculated bounding box. */ - bool _bValid{true}; /**< Current state of validality. */ + MeshPointArray _aclPointArray; /**< Holds the array of geometric points. */ + MeshFacetArray _aclFacetArray; /**< Holds the array of facets. */ + mutable Base::BoundBox3f _clBoundBox; /**< The current calculated bounding box. */ + bool _bValid {true}; /**< Current state of validality. */ // friends friend class MeshPointIterator; @@ -461,46 +495,48 @@ protected: friend class MeshTrimming; }; -inline MeshPoint MeshKernel::GetPoint (PointIndex ulIndex) const +inline MeshPoint MeshKernel::GetPoint(PointIndex ulIndex) const { assert(ulIndex < _aclPointArray.size()); return _aclPointArray[ulIndex]; } -inline MeshGeomFacet MeshKernel::GetFacet (FacetIndex ulIndex) const +inline MeshGeomFacet MeshKernel::GetFacet(FacetIndex ulIndex) const { assert(ulIndex < _aclFacetArray.size()); - const MeshFacet *pclF = &_aclFacetArray[ulIndex]; - MeshGeomFacet clFacet; + const MeshFacet* pclF = &_aclFacetArray[ulIndex]; + MeshGeomFacet clFacet; clFacet._aclPoints[0] = _aclPointArray[pclF->_aulPoints[0]]; clFacet._aclPoints[1] = _aclPointArray[pclF->_aulPoints[1]]; clFacet._aclPoints[2] = _aclPointArray[pclF->_aulPoints[2]]; - clFacet._ulProp = pclF->_ulProp; - clFacet._ucFlag = pclF->_ucFlag; + clFacet._ulProp = pclF->_ulProp; + clFacet._ucFlag = pclF->_ucFlag; clFacet.CalcNormal(); return clFacet; } -inline MeshGeomFacet MeshKernel::GetFacet (const MeshFacet &rclFacet) const +inline MeshGeomFacet MeshKernel::GetFacet(const MeshFacet& rclFacet) const { assert(rclFacet._aulPoints[0] < _aclPointArray.size()); assert(rclFacet._aulPoints[1] < _aclPointArray.size()); assert(rclFacet._aulPoints[2] < _aclPointArray.size()); - MeshGeomFacet clFacet; + MeshGeomFacet clFacet; clFacet._aclPoints[0] = _aclPointArray[rclFacet._aulPoints[0]]; clFacet._aclPoints[1] = _aclPointArray[rclFacet._aulPoints[1]]; clFacet._aclPoints[2] = _aclPointArray[rclFacet._aulPoints[2]]; - clFacet._ulProp = rclFacet._ulProp; - clFacet._ucFlag = rclFacet._ucFlag; + clFacet._ulProp = rclFacet._ulProp; + clFacet._ucFlag = rclFacet._ucFlag; clFacet.CalcNormal(); - return clFacet; + return clFacet; } -inline void MeshKernel::GetFacetNeighbours (FacetIndex ulIndex, FacetIndex &rulNIdx0, - FacetIndex &rulNIdx1, FacetIndex &rulNIdx2) const +inline void MeshKernel::GetFacetNeighbours(FacetIndex ulIndex, + FacetIndex& rulNIdx0, + FacetIndex& rulNIdx1, + FacetIndex& rulNIdx2) const { assert(ulIndex < _aclFacetArray.size()); @@ -509,50 +545,54 @@ inline void MeshKernel::GetFacetNeighbours (FacetIndex ulIndex, FacetIndex &rulN rulNIdx2 = _aclFacetArray[ulIndex]._aulNeighbours[2]; } -inline void MeshKernel::MovePoint (PointIndex ulPtIndex, const Base::Vector3f &rclTrans) +inline void MeshKernel::MovePoint(PointIndex ulPtIndex, const Base::Vector3f& rclTrans) { _aclPointArray[ulPtIndex] += rclTrans; } -inline void MeshKernel::SetPoint (PointIndex ulPtIndex, const Base::Vector3f &rPoint) +inline void MeshKernel::SetPoint(PointIndex ulPtIndex, const Base::Vector3f& rPoint) { _aclPointArray[ulPtIndex] = rPoint; } -inline void MeshKernel::SetPoint (PointIndex ulPtIndex, float x, float y, float z) +inline void MeshKernel::SetPoint(PointIndex ulPtIndex, float x, float y, float z) { - _aclPointArray[ulPtIndex].Set(x,y,z); + _aclPointArray[ulPtIndex].Set(x, y, z); } -inline void MeshKernel::AdjustNormal (MeshFacet &rclFacet, const Base::Vector3f &rclNormal) +inline void MeshKernel::AdjustNormal(MeshFacet& rclFacet, const Base::Vector3f& rclNormal) { - Base::Vector3f clN = (_aclPointArray[rclFacet._aulPoints[1]] - _aclPointArray[rclFacet._aulPoints[0]]) % - (_aclPointArray[rclFacet._aulPoints[2]] - _aclPointArray[rclFacet._aulPoints[0]]); + Base::Vector3f clN = + (_aclPointArray[rclFacet._aulPoints[1]] - _aclPointArray[rclFacet._aulPoints[0]]) + % (_aclPointArray[rclFacet._aulPoints[2]] - _aclPointArray[rclFacet._aulPoints[0]]); if ((clN * rclNormal) < 0.0f) { rclFacet.FlipNormal(); } } -inline Base::Vector3f MeshKernel::GetNormal (const MeshFacet &rclFacet) const +inline Base::Vector3f MeshKernel::GetNormal(const MeshFacet& rclFacet) const { - Base::Vector3f clN = (_aclPointArray[rclFacet._aulPoints[1]] - _aclPointArray[rclFacet._aulPoints[0]]) % - (_aclPointArray[rclFacet._aulPoints[2]] - _aclPointArray[rclFacet._aulPoints[0]]); + Base::Vector3f clN = + (_aclPointArray[rclFacet._aulPoints[1]] - _aclPointArray[rclFacet._aulPoints[0]]) + % (_aclPointArray[rclFacet._aulPoints[2]] - _aclPointArray[rclFacet._aulPoints[0]]); clN.Normalize(); return clN; } -inline Base::Vector3f MeshKernel::GetGravityPoint (const MeshFacet &rclFacet) const +inline Base::Vector3f MeshKernel::GetGravityPoint(const MeshFacet& rclFacet) const { const Base::Vector3f& p0 = _aclPointArray[rclFacet._aulPoints[0]]; const Base::Vector3f& p1 = _aclPointArray[rclFacet._aulPoints[1]]; const Base::Vector3f& p2 = _aclPointArray[rclFacet._aulPoints[2]]; - return Base::Vector3f((p0.x+p1.x+p2.x)/3.0f, - (p0.y+p1.y+p2.y)/3.0f, - (p0.z+p1.z+p2.z)/3.0f); + return Base::Vector3f((p0.x + p1.x + p2.x) / 3.0f, + (p0.y + p1.y + p2.y) / 3.0f, + (p0.z + p1.z + p2.z) / 3.0f); } -inline void MeshKernel::GetFacetPoints (FacetIndex ulFaIndex, PointIndex &rclP0, - PointIndex &rclP1, PointIndex &rclP2) const +inline void MeshKernel::GetFacetPoints(FacetIndex ulFaIndex, + PointIndex& rclP0, + PointIndex& rclP1, + PointIndex& rclP2) const { assert(ulFaIndex < _aclFacetArray.size()); const MeshFacet& rclFacet = _aclFacetArray[ulFaIndex]; @@ -561,8 +601,10 @@ inline void MeshKernel::GetFacetPoints (FacetIndex ulFaIndex, PointIndex &rclP0, rclP2 = rclFacet._aulPoints[2]; } -inline void MeshKernel::SetFacetPoints (FacetIndex ulFaIndex, PointIndex rclP0, - PointIndex rclP1, PointIndex rclP2) +inline void MeshKernel::SetFacetPoints(FacetIndex ulFaIndex, + PointIndex rclP0, + PointIndex rclP1, + PointIndex rclP2) { assert(ulFaIndex < _aclFacetArray.size()); MeshFacet& rclFacet = _aclFacetArray[ulFaIndex]; @@ -572,6 +614,6 @@ inline void MeshKernel::SetFacetPoints (FacetIndex ulFaIndex, PointIndex rclP0, } -} // namespace MeshCore +} // namespace MeshCore -#endif // MESH_KERNEL_H +#endif // MESH_KERNEL_H diff --git a/src/Mod/Mesh/App/Core/Projection.cpp b/src/Mod/Mesh/App/Core/Projection.cpp index cd80d9b6c4..0f66047541 100644 --- a/src/Mod/Mesh/App/Core/Projection.cpp +++ b/src/Mod/Mesh/App/Core/Projection.cpp @@ -22,14 +22,14 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include +#include +#include #endif -#include "Projection.h" #include "Grid.h" #include "Iterator.h" #include "MeshKernel.h" +#include "Projection.h" using namespace MeshCore; @@ -37,9 +37,8 @@ using namespace MeshCore; // ------------------------------------------------------------------------ MeshProjection::MeshProjection(const MeshKernel& mesh) - : kernel(mesh) -{ -} + : kernel(mesh) +{} bool MeshProjection::bboxInsideRectangle(const Base::BoundBox3f& bbox, const Base::Vector3f& p1, @@ -54,16 +53,16 @@ bool MeshProjection::bboxInsideRectangle(const Base::BoundBox3f& bbox, dir.Normalize(); Base::Vector3f cnt(bbox.GetCenter()); - return (fabs(cnt.DistanceToPlane(p1, dir)) + fabs(cnt.DistanceToPlane(p2, dir))) <= - (bbox.CalcDiagonalLength() + (p2 - p1).Length()); + return (fabs(cnt.DistanceToPlane(p1, dir)) + fabs(cnt.DistanceToPlane(p2, dir))) + <= (bbox.CalcDiagonalLength() + (p2 - p1).Length()); } return false; } -bool MeshProjection::isPointInsideDistance (const Base::Vector3f& p1, - const Base::Vector3f& p2, - const Base::Vector3f& pt) const +bool MeshProjection::isPointInsideDistance(const Base::Vector3f& p1, + const Base::Vector3f& p2, + const Base::Vector3f& pt) const { // project point on line Base::Vector3f proj, dir(p2 - p1); @@ -73,46 +72,50 @@ bool MeshProjection::isPointInsideDistance (const Base::Vector3f& p1, return (((p1 - proj) * (p2 - proj)) < 0.0f); } -bool MeshProjection::connectLines(std::list< std::pair >& cutLines, - const Base::Vector3f& startPoint, const Base::Vector3f& endPoint, +bool MeshProjection::connectLines(std::list>& cutLines, + const Base::Vector3f& startPoint, + const Base::Vector3f& endPoint, std::vector& polyline) const { - const float fMaxDist = float(sqrt(FLOAT_MAX)); // max. length of a gap - const float fMinEps = 1.0e-4f; + const float fMaxDist = float(sqrt(FLOAT_MAX)); // max. length of a gap + const float fMinEps = 1.0e-4f; polyline.clear(); polyline.push_back(startPoint); Base::Vector3f curr(startPoint); while ((curr != endPoint) && (!cutLines.empty())) { - std::list< std::pair >::iterator it, pCurr = cutLines.end(); + std::list>::iterator it, pCurr = cutLines.end(); // get nearest line - float fMin = fMaxDist * fMaxDist; + float fMin = fMaxDist * fMaxDist; - bool bPos = false; + bool bPos = false; for (it = cutLines.begin(); it != cutLines.end(); ++it) { float fD1 = Base::DistanceP2(curr, it->first); float fD2 = Base::DistanceP2(curr, it->second); if (std::min(fD1, fD2) < fMin) { pCurr = it; - bPos = fD1 < fD2; - fMin = std::min(fD1, fD2); - if (fMin < fMinEps) // abort because next line already found + bPos = fD1 < fD2; + fMin = std::min(fD1, fD2); + if (fMin < fMinEps) { // abort because next line already found break; + } } } if (pCurr != cutLines.end()) { if (bPos) { - if (fMin > fMinEps) // gap, insert point + if (fMin > fMinEps) { // gap, insert point polyline.push_back(pCurr->first); + } polyline.push_back(pCurr->second); curr = pCurr->second; } else { - if (fMin > fMinEps) // gap, insert point + if (fMin > fMinEps) { // gap, insert point polyline.push_back(pCurr->second); + } polyline.push_back(pCurr->first); curr = pCurr->first; } @@ -128,8 +131,10 @@ bool MeshProjection::connectLines(std::list< std::pair& polyline) { @@ -152,15 +157,16 @@ bool MeshProjection::projectLineOnMesh(const MeshFacetGrid& grid, MeshGridIterator gridIter(grid); for (gridIter.Init(); gridIter.More(); gridIter.Next()) { // bbox cuts plane - if (bboxInsideRectangle(gridIter.GetBoundBox(), v1, v2, vd)) + if (bboxInsideRectangle(gridIter.GetBoundBox(), v1, v2, vd)) { gridIter.GetElements(facets); + } } std::sort(facets.begin(), facets.end()); facets.erase(std::unique(facets.begin(), facets.end()), facets.end()); // cut all facets with plane - std::list< std::pair > cutLine; + std::list> cutLine; for (FacetIndex facet : facets) { Base::Vector3f e1, e2; MeshGeomFacet tria = kernel.GetFacet(facet); @@ -168,30 +174,33 @@ bool MeshProjection::projectLineOnMesh(const MeshFacetGrid& grid, if (tria.IntersectWithPlane(base, normal, e1, e2)) { if ((facet != f1) && (facet != f2)) { // inside cut line - if (!isPointInsideDistance(v1, v2, e1) || - !isPointInsideDistance(v1, v2, e2)) { + if (!isPointInsideDistance(v1, v2, e1) || !isPointInsideDistance(v1, v2, e2)) { continue; } cutLine.emplace_back(e1, e2); } else { - if (facet == f1) { // start facet - if (((e2 - v1) * dir) > 0.0f) + if (facet == f1) { // start facet + if (((e2 - v1) * dir) > 0.0f) { cutLine.emplace_back(v1, e2); - else + } + else { cutLine.emplace_back(v1, e1); + } - //start = it - facets.begin(); + // start = it - facets.begin(); } - if (facet == f2) { // end facet - if (((e2 - v2) * -dir) > 0.0f) + if (facet == f2) { // end facet + if (((e2 - v2) * -dir) > 0.0f) { cutLine.emplace_back(v2, e2); - else + } + else { cutLine.emplace_back(v2, e1); + } - //end = it - facets.begin(); + // end = it - facets.begin(); } } } diff --git a/src/Mod/Mesh/App/Core/Projection.h b/src/Mod/Mesh/App/Core/Projection.h index dba05e0920..2ba5551301 100644 --- a/src/Mod/Mesh/App/Core/Projection.h +++ b/src/Mod/Mesh/App/Core/Projection.h @@ -23,8 +23,8 @@ #ifndef MESH_PROJECTION_H #define MESH_PROJECTION_H -#include #include +#include #include "Elements.h" @@ -48,19 +48,31 @@ class MeshExport MeshProjection public: explicit MeshProjection(const MeshKernel&); - bool projectLineOnMesh(const MeshFacetGrid& grid, const Base::Vector3f& p1, FacetIndex f1, - const Base::Vector3f& p2, FacetIndex f2, const Base::Vector3f& view, - std::vector& polyline); + bool projectLineOnMesh(const MeshFacetGrid& grid, + const Base::Vector3f& p1, + FacetIndex f1, + const Base::Vector3f& p2, + FacetIndex f2, + const Base::Vector3f& view, + std::vector& polyline); + protected: - bool bboxInsideRectangle (const Base::BoundBox3f& bbox, const Base::Vector3f& p1, const Base::Vector3f& p2, const Base::Vector3f& view) const; - bool isPointInsideDistance (const Base::Vector3f& p1, const Base::Vector3f& p2, const Base::Vector3f& pt) const; - bool connectLines(std::list< std::pair >& cutLines, const Base::Vector3f& startPoint, - const Base::Vector3f& endPoint, std::vector& polyline) const; + bool bboxInsideRectangle(const Base::BoundBox3f& bbox, + const Base::Vector3f& p1, + const Base::Vector3f& p2, + const Base::Vector3f& view) const; + bool isPointInsideDistance(const Base::Vector3f& p1, + const Base::Vector3f& p2, + const Base::Vector3f& pt) const; + bool connectLines(std::list>& cutLines, + const Base::Vector3f& startPoint, + const Base::Vector3f& endPoint, + std::vector& polyline) const; private: const MeshKernel& kernel; }; -} // namespace MeshCore +} // namespace MeshCore #endif // MESH_PROJECTION_H diff --git a/src/Mod/Mesh/App/Core/Segmentation.cpp b/src/Mod/Mesh/App/Core/Segmentation.cpp index df265d0359..dd4bde4e3b 100644 --- a/src/Mod/Mesh/App/Core/Segmentation.cpp +++ b/src/Mod/Mesh/App/Core/Segmentation.cpp @@ -25,15 +25,14 @@ #include #endif -#include "Segmentation.h" #include "Algorithm.h" #include "Approximation.h" +#include "Segmentation.h" using namespace MeshCore; void MeshSurfaceSegment::Initialize(FacetIndex) -{ -} +{} bool MeshSurfaceSegment::TestInitialFacet(FacetIndex) const { @@ -41,8 +40,7 @@ bool MeshSurfaceSegment::TestInitialFacet(FacetIndex) const } void MeshSurfaceSegment::AddFacet(const MeshFacet&) -{ -} +{} void MeshSurfaceSegment::AddSegment(const std::vector& segm) { @@ -53,9 +51,10 @@ void MeshSurfaceSegment::AddSegment(const std::vector& segm) MeshSegment MeshSurfaceSegment::FindSegment(FacetIndex index) const { - for (const auto & segment : segments) { - if (std::find(segment.begin(), segment.end(), index) != segment.end()) + for (const auto& segment : segments) { + if (std::find(segment.begin(), segment.end(), index) != segment.end()) { return segment; + } } return {}; @@ -63,10 +62,12 @@ MeshSegment MeshSurfaceSegment::FindSegment(FacetIndex index) const // -------------------------------------------------------- -MeshDistancePlanarSegment::MeshDistancePlanarSegment(const MeshKernel& mesh, unsigned long minFacets, float tol) - : MeshDistanceSurfaceSegment(mesh, minFacets, tol), fitter(new PlaneFit) -{ -} +MeshDistancePlanarSegment::MeshDistancePlanarSegment(const MeshKernel& mesh, + unsigned long minFacets, + float tol) + : MeshDistanceSurfaceSegment(mesh, minFacets, tol) + , fitter(new PlaneFit) +{} MeshDistancePlanarSegment::~MeshDistancePlanarSegment() { @@ -85,14 +86,16 @@ void MeshDistancePlanarSegment::Initialize(FacetIndex index) fitter->AddPoint(triangle._aclPoints[2]); } -bool MeshDistancePlanarSegment::TestFacet (const MeshFacet& face) const +bool MeshDistancePlanarSegment::TestFacet(const MeshFacet& face) const { - if (!fitter->Done()) + if (!fitter->Done()) { fitter->Fit(); + } MeshGeomFacet triangle = kernel.GetFacet(face); for (auto pnt : triangle._aclPoints) { - if (fabs(fitter->GetDistanceToPlane(pnt)) > tolerance) + if (fabs(fitter->GetDistanceToPlane(pnt)) > tolerance) { return false; + } } return true; @@ -108,15 +111,13 @@ void MeshDistancePlanarSegment::AddFacet(const MeshFacet& face) PlaneSurfaceFit::PlaneSurfaceFit() : fitter(new PlaneFit) -{ -} +{} PlaneSurfaceFit::PlaneSurfaceFit(const Base::Vector3f& b, const Base::Vector3f& n) : basepoint(b) , normal(n) , fitter(nullptr) -{ -} +{} PlaneSurfaceFit::~PlaneSurfaceFit() { @@ -145,32 +146,39 @@ bool PlaneSurfaceFit::TestTriangle(const MeshGeomFacet&) const void PlaneSurfaceFit::AddTriangle(const MeshCore::MeshGeomFacet& tria) { - if (fitter) + if (fitter) { fitter->AddPoint(tria.GetGravityPoint()); + } } bool PlaneSurfaceFit::Done() const { - if (!fitter) + if (!fitter) { return true; - else + } + else { return fitter->Done(); + } } float PlaneSurfaceFit::Fit() { - if (!fitter) + if (!fitter) { return 0; - else + } + else { return fitter->Fit(); + } } float PlaneSurfaceFit::GetDistanceToSurface(const Base::Vector3f& pnt) const { - if (!fitter) + if (!fitter) { return pnt.DistanceToPlane(basepoint, normal); - else + } + else { return fitter->GetDistanceToPlane(pnt); + } } std::vector PlaneSurfaceFit::Parameters() const @@ -197,7 +205,7 @@ std::vector PlaneSurfaceFit::Parameters() const CylinderSurfaceFit::CylinderSurfaceFit() : fitter(new CylinderFit) { - axis.Set(0,0,0); + axis.Set(0, 0, 0); radius = FLOAT_MAX; } @@ -210,8 +218,7 @@ CylinderSurfaceFit::CylinderSurfaceFit(const Base::Vector3f& b, const Base::Vect , axis(a) , radius(r) , fitter(nullptr) -{ -} +{} CylinderSurfaceFit::~CylinderSurfaceFit() { @@ -256,8 +263,9 @@ bool CylinderSurfaceFit::Done() const float CylinderSurfaceFit::Fit() { - if (!fitter) + if (!fitter) { return 0; + } float fit = fitter->Fit(); if (fit < FLOAT_MAX) { @@ -305,7 +313,7 @@ std::vector CylinderSurfaceFit::Parameters() const SphereSurfaceFit::SphereSurfaceFit() : fitter(new SphereFit) { - center.Set(0,0,0); + center.Set(0, 0, 0); radius = FLOAT_MAX; } @@ -313,9 +321,7 @@ SphereSurfaceFit::SphereSurfaceFit(const Base::Vector3f& c, float r) : center(c) , radius(r) , fitter(nullptr) -{ - -} +{} SphereSurfaceFit::~SphereSurfaceFit() { @@ -358,8 +364,9 @@ bool SphereSurfaceFit::Done() const float SphereSurfaceFit::Fit() { - if (!fitter) + if (!fitter) { return 0; + } float fit = fitter->Fit(); if (fit < FLOAT_MAX) { @@ -398,10 +405,9 @@ MeshDistanceGenericSurfaceFitSegment::MeshDistanceGenericSurfaceFitSegment(Abstr const MeshKernel& mesh, unsigned long minFacets, float tol) - : MeshDistanceSurfaceSegment(mesh, minFacets, tol) - , fitter(fit) -{ -} + : MeshDistanceSurfaceSegment(mesh, minFacets, tol) + , fitter(fit) +{} MeshDistanceGenericSurfaceFitSegment::~MeshDistanceGenericSurfaceFitSegment() { @@ -418,20 +424,23 @@ bool MeshDistanceGenericSurfaceFitSegment::TestInitialFacet(FacetIndex index) co { MeshGeomFacet triangle = kernel.GetFacet(index); for (auto pnt : triangle._aclPoints) { - if (fabs(fitter->GetDistanceToSurface(pnt)) > tolerance) + if (fabs(fitter->GetDistanceToSurface(pnt)) > tolerance) { return false; + } } return fitter->TestTriangle(triangle); } -bool MeshDistanceGenericSurfaceFitSegment::TestFacet (const MeshFacet& face) const +bool MeshDistanceGenericSurfaceFitSegment::TestFacet(const MeshFacet& face) const { - if (!fitter->Done()) + if (!fitter->Done()) { fitter->Fit(); + } MeshGeomFacet triangle = kernel.GetFacet(face); for (auto ptIndex : triangle._aclPoints) { - if (fabs(fitter->GetDistanceToSurface(ptIndex)) > tolerance) + if (fabs(fitter->GetDistanceToSurface(ptIndex)) > tolerance) { return false; + } } return fitter->TestTriangle(triangle); @@ -450,60 +459,69 @@ std::vector MeshDistanceGenericSurfaceFitSegment::Parameters() const // -------------------------------------------------------- -bool MeshCurvaturePlanarSegment::TestFacet (const MeshFacet &rclFacet) const +bool MeshCurvaturePlanarSegment::TestFacet(const MeshFacet& rclFacet) const { for (PointIndex ptIndex : rclFacet._aulPoints) { const CurvatureInfo& ci = info[ptIndex]; - if (fabs(ci.fMinCurvature) > tolerance) + if (fabs(ci.fMinCurvature) > tolerance) { return false; - if (fabs(ci.fMaxCurvature) > tolerance) + } + if (fabs(ci.fMaxCurvature) > tolerance) { return false; + } } return true; } -bool MeshCurvatureCylindricalSegment::TestFacet (const MeshFacet &rclFacet) const +bool MeshCurvatureCylindricalSegment::TestFacet(const MeshFacet& rclFacet) const { for (PointIndex ptIndex : rclFacet._aulPoints) { const CurvatureInfo& ci = info[ptIndex]; float fMax = std::max(fabs(ci.fMaxCurvature), fabs(ci.fMinCurvature)); float fMin = std::min(fabs(ci.fMaxCurvature), fabs(ci.fMinCurvature)); - if (fMin > toleranceMin) + if (fMin > toleranceMin) { return false; - if (fabs(fMax - curvature) > toleranceMax) + } + if (fabs(fMax - curvature) > toleranceMax) { return false; + } } return true; } -bool MeshCurvatureSphericalSegment::TestFacet (const MeshFacet &rclFacet) const +bool MeshCurvatureSphericalSegment::TestFacet(const MeshFacet& rclFacet) const { for (PointIndex ptIndex : rclFacet._aulPoints) { const CurvatureInfo& ci = info[ptIndex]; - if (ci.fMaxCurvature * ci.fMinCurvature < 0) + if (ci.fMaxCurvature * ci.fMinCurvature < 0) { return false; + } float diff; diff = fabs(ci.fMinCurvature) - curvature; - if (fabs(diff) > tolerance) + if (fabs(diff) > tolerance) { return false; + } diff = fabs(ci.fMaxCurvature) - curvature; - if (fabs(diff) > tolerance) + if (fabs(diff) > tolerance) { return false; + } } return true; } -bool MeshCurvatureFreeformSegment::TestFacet (const MeshFacet &rclFacet) const +bool MeshCurvatureFreeformSegment::TestFacet(const MeshFacet& rclFacet) const { for (PointIndex ptIndex : rclFacet._aulPoints) { const CurvatureInfo& ci = info[ptIndex]; - if (fabs(ci.fMinCurvature-c2) > toleranceMin) + if (fabs(ci.fMinCurvature - c2) > toleranceMin) { return false; - if (fabs(ci.fMaxCurvature-c1) > toleranceMax) + } + if (fabs(ci.fMaxCurvature - c1) > toleranceMax) { return false; + } } return true; @@ -511,19 +529,24 @@ bool MeshCurvatureFreeformSegment::TestFacet (const MeshFacet &rclFacet) const // -------------------------------------------------------- -MeshSurfaceVisitor::MeshSurfaceVisitor (MeshSurfaceSegment& segm, std::vector &indices) - : indices(indices), segm(segm) -{ -} +MeshSurfaceVisitor::MeshSurfaceVisitor(MeshSurfaceSegment& segm, std::vector& indices) + : indices(indices) + , segm(segm) +{} -bool MeshSurfaceVisitor::AllowVisit (const MeshFacet& face, const MeshFacet&, - FacetIndex, unsigned long, unsigned short) +bool MeshSurfaceVisitor::AllowVisit(const MeshFacet& face, + const MeshFacet&, + FacetIndex, + unsigned long, + unsigned short) { return segm.TestFacet(face); } -bool MeshSurfaceVisitor::Visit (const MeshFacet & face, const MeshFacet &, - FacetIndex ulFInd, unsigned long) +bool MeshSurfaceVisitor::Visit(const MeshFacet& face, + const MeshFacet&, + FacetIndex ulFInd, + unsigned long) { indices.push_back(ulFInd); segm.AddFacet(face); @@ -548,7 +571,7 @@ void MeshSegmentAlgorithm::FindSegments(std::vector& segm cAlgo.CountFacetFlag(MeshCore::MeshFacet::VISIT); std::vector resetVisited; - for (auto & it : segm) { + for (auto& it : segm) { cAlgo.ResetFacetsFlag(resetVisited, MeshCore::MeshFacet::VISIT); resetVisited.clear(); @@ -556,16 +579,19 @@ void MeshSegmentAlgorithm::FindSegments(std::vector& segm iCur = std::find_if(iBeg, iEnd, [flag](const MeshFacet& f) { return flag(f, MeshFacet::VISIT); }); - if (iCur < iEnd) + if (iCur < iEnd) { startFacet = iCur - iBeg; - else + } + else { startFacet = FACET_INDEX_MAX; + } while (startFacet != FACET_INDEX_MAX) { // collect all facets of the same geometry std::vector indices; it->Initialize(startFacet); - if (it->TestInitialFacet(startFacet)) + if (it->TestInitialFacet(startFacet)) { indices.push_back(startFacet); + } MeshSurfaceVisitor pv(*it, indices); myKernel.VisitNeighbourFacets(pv, startFacet); @@ -581,10 +607,12 @@ void MeshSegmentAlgorithm::FindSegments(std::vector& segm iCur = std::find_if(iCur, iEnd, [flag](const MeshFacet& f) { return flag(f, MeshFacet::VISIT); }); - if (iCur < iEnd) + if (iCur < iEnd) { startFacet = iCur - iBeg; - else + } + else { startFacet = FACET_INDEX_MAX; + } } } } diff --git a/src/Mod/Mesh/App/Core/Segmentation.h b/src/Mod/Mesh/App/Core/Segmentation.h index 1941770a51..ad7fe653e2 100644 --- a/src/Mod/Mesh/App/Core/Segmentation.h +++ b/src/Mod/Mesh/App/Core/Segmentation.h @@ -31,7 +31,8 @@ #include "Visitor.h" -namespace MeshCore { +namespace MeshCore +{ class PlaneFit; class CylinderFit; @@ -43,15 +44,19 @@ class MeshExport MeshSurfaceSegment { public: explicit MeshSurfaceSegment(unsigned long minFacets) - : minFacets(minFacets) {} + : minFacets(minFacets) + {} virtual ~MeshSurfaceSegment() = default; - virtual bool TestFacet (const MeshFacet &rclFacet) const = 0; + virtual bool TestFacet(const MeshFacet& rclFacet) const = 0; virtual const char* GetType() const = 0; virtual void Initialize(FacetIndex); virtual bool TestInitialFacet(FacetIndex) const; virtual void AddFacet(const MeshFacet& rclFacet); void AddSegment(const std::vector&); - const std::vector& GetSegments() const { return segments; } + const std::vector& GetSegments() const + { + return segments; + } MeshSegment FindSegment(FacetIndex) const; protected: @@ -62,24 +67,30 @@ using MeshSurfaceSegmentPtr = std::shared_ptr; // -------------------------------------------------------- -class MeshExport MeshDistanceSurfaceSegment : public MeshSurfaceSegment +class MeshExport MeshDistanceSurfaceSegment: public MeshSurfaceSegment { public: MeshDistanceSurfaceSegment(const MeshKernel& mesh, unsigned long minFacets, float tol) - : MeshSurfaceSegment(minFacets), kernel(mesh), tolerance(tol) {} + : MeshSurfaceSegment(minFacets) + , kernel(mesh) + , tolerance(tol) + {} protected: const MeshKernel& kernel; float tolerance; }; -class MeshExport MeshDistancePlanarSegment : public MeshDistanceSurfaceSegment +class MeshExport MeshDistancePlanarSegment: public MeshDistanceSurfaceSegment { public: MeshDistancePlanarSegment(const MeshKernel& mesh, unsigned long minFacets, float tol); ~MeshDistancePlanarSegment() override; - bool TestFacet (const MeshFacet& rclFacet) const override; - const char* GetType() const override { return "Plane"; } + bool TestFacet(const MeshFacet& rclFacet) const override; + const char* GetType() const override + { + return "Plane"; + } void Initialize(FacetIndex) override; void AddFacet(const MeshFacet& rclFacet) override; @@ -104,13 +115,16 @@ public: virtual std::vector Parameters() const = 0; }; -class MeshExport PlaneSurfaceFit : public AbstractSurfaceFit +class MeshExport PlaneSurfaceFit: public AbstractSurfaceFit { public: PlaneSurfaceFit(); PlaneSurfaceFit(const Base::Vector3f& b, const Base::Vector3f& n); ~PlaneSurfaceFit() override; - const char* GetType() const override { return "Plane"; } + const char* GetType() const override + { + return "Plane"; + } void Initialize(const MeshGeomFacet&) override; bool TestTriangle(const MeshGeomFacet&) const override; void AddTriangle(const MeshGeomFacet&) override; @@ -125,13 +139,16 @@ private: PlaneFit* fitter; }; -class MeshExport CylinderSurfaceFit : public AbstractSurfaceFit +class MeshExport CylinderSurfaceFit: public AbstractSurfaceFit { public: CylinderSurfaceFit(); CylinderSurfaceFit(const Base::Vector3f& b, const Base::Vector3f& a, float r); ~CylinderSurfaceFit() override; - const char* GetType() const override { return "Cylinder"; } + const char* GetType() const override + { + return "Cylinder"; + } void Initialize(const MeshGeomFacet&) override; bool TestTriangle(const MeshGeomFacet&) const override; void AddTriangle(const MeshGeomFacet&) override; @@ -147,13 +164,16 @@ private: CylinderFit* fitter; }; -class MeshExport SphereSurfaceFit : public AbstractSurfaceFit +class MeshExport SphereSurfaceFit: public AbstractSurfaceFit { public: SphereSurfaceFit(); SphereSurfaceFit(const Base::Vector3f& c, float r); ~SphereSurfaceFit() override; - const char* GetType() const override { return "Sphere"; } + const char* GetType() const override + { + return "Sphere"; + } void Initialize(const MeshGeomFacet&) override; bool TestTriangle(const MeshGeomFacet&) const override; void AddTriangle(const MeshGeomFacet&) override; @@ -168,14 +188,19 @@ private: SphereFit* fitter; }; -class MeshExport MeshDistanceGenericSurfaceFitSegment : public MeshDistanceSurfaceSegment +class MeshExport MeshDistanceGenericSurfaceFitSegment: public MeshDistanceSurfaceSegment { public: - MeshDistanceGenericSurfaceFitSegment(AbstractSurfaceFit*, const MeshKernel& mesh, - unsigned long minFacets, float tol); + MeshDistanceGenericSurfaceFitSegment(AbstractSurfaceFit*, + const MeshKernel& mesh, + unsigned long minFacets, + float tol); ~MeshDistanceGenericSurfaceFitSegment() override; - bool TestFacet (const MeshFacet& rclFacet) const override; - const char* GetType() const override { return fitter->GetType(); } + bool TestFacet(const MeshFacet& rclFacet) const override; + const char* GetType() const override + { + return fitter->GetType(); + } void Initialize(FacetIndex) override; bool TestInitialFacet(FacetIndex) const override; void AddFacet(const MeshFacet& rclFacet) override; @@ -187,36 +212,56 @@ protected: // -------------------------------------------------------- -class MeshExport MeshCurvatureSurfaceSegment : public MeshSurfaceSegment +class MeshExport MeshCurvatureSurfaceSegment: public MeshSurfaceSegment { public: MeshCurvatureSurfaceSegment(const std::vector& ci, unsigned long minFacets) - : MeshSurfaceSegment(minFacets), info(ci) {} + : MeshSurfaceSegment(minFacets) + , info(ci) + {} protected: const std::vector& info; }; -class MeshExport MeshCurvaturePlanarSegment : public MeshCurvatureSurfaceSegment +class MeshExport MeshCurvaturePlanarSegment: public MeshCurvatureSurfaceSegment { public: - MeshCurvaturePlanarSegment(const std::vector& ci, unsigned long minFacets, float tol) - : MeshCurvatureSurfaceSegment(ci, minFacets), tolerance(tol) {} - bool TestFacet (const MeshFacet &rclFacet) const override; - const char* GetType() const override { return "Plane"; } + MeshCurvaturePlanarSegment(const std::vector& ci, + unsigned long minFacets, + float tol) + : MeshCurvatureSurfaceSegment(ci, minFacets) + , tolerance(tol) + {} + bool TestFacet(const MeshFacet& rclFacet) const override; + const char* GetType() const override + { + return "Plane"; + } private: float tolerance; }; -class MeshExport MeshCurvatureCylindricalSegment : public MeshCurvatureSurfaceSegment +class MeshExport MeshCurvatureCylindricalSegment: public MeshCurvatureSurfaceSegment { public: - MeshCurvatureCylindricalSegment(const std::vector& ci, unsigned long minFacets, - float tolMin, float tolMax, float curv) - : MeshCurvatureSurfaceSegment(ci, minFacets), toleranceMin(tolMin), toleranceMax(tolMax) { curvature = curv;} - bool TestFacet (const MeshFacet &rclFacet) const override; - const char* GetType() const override { return "Cylinder"; } + MeshCurvatureCylindricalSegment(const std::vector& ci, + unsigned long minFacets, + float tolMin, + float tolMax, + float curv) + : MeshCurvatureSurfaceSegment(ci, minFacets) + , toleranceMin(tolMin) + , toleranceMax(tolMax) + { + curvature = curv; + } + bool TestFacet(const MeshFacet& rclFacet) const override; + const char* GetType() const override + { + return "Cylinder"; + } private: float curvature; @@ -224,28 +269,49 @@ private: float toleranceMax; }; -class MeshExport MeshCurvatureSphericalSegment : public MeshCurvatureSurfaceSegment +class MeshExport MeshCurvatureSphericalSegment: public MeshCurvatureSurfaceSegment { public: - MeshCurvatureSphericalSegment(const std::vector& ci, unsigned long minFacets, float tol, float curv) - : MeshCurvatureSurfaceSegment(ci, minFacets), tolerance(tol) { curvature = curv;} - bool TestFacet (const MeshFacet &rclFacet) const override; - const char* GetType() const override { return "Sphere"; } + MeshCurvatureSphericalSegment(const std::vector& ci, + unsigned long minFacets, + float tol, + float curv) + : MeshCurvatureSurfaceSegment(ci, minFacets) + , tolerance(tol) + { + curvature = curv; + } + bool TestFacet(const MeshFacet& rclFacet) const override; + const char* GetType() const override + { + return "Sphere"; + } private: float curvature; float tolerance; }; -class MeshExport MeshCurvatureFreeformSegment : public MeshCurvatureSurfaceSegment +class MeshExport MeshCurvatureFreeformSegment: public MeshCurvatureSurfaceSegment { public: - MeshCurvatureFreeformSegment(const std::vector& ci, unsigned long minFacets, - float tolMin, float tolMax, float c1, float c2) - : MeshCurvatureSurfaceSegment(ci, minFacets), c1(c1), c2(c2), - toleranceMin(tolMin), toleranceMax(tolMax) {} - bool TestFacet (const MeshFacet &rclFacet) const override; - const char* GetType() const override { return "Freeform"; } + MeshCurvatureFreeformSegment(const std::vector& ci, + unsigned long minFacets, + float tolMin, + float tolMax, + float c1, + float c2) + : MeshCurvatureSurfaceSegment(ci, minFacets) + , c1(c1) + , c2(c2) + , toleranceMin(tolMin) + , toleranceMax(tolMax) + {} + bool TestFacet(const MeshFacet& rclFacet) const override; + const char* GetType() const override + { + return "Freeform"; + } private: float c1, c2; @@ -253,30 +319,34 @@ private: float toleranceMax; }; -class MeshExport MeshSurfaceVisitor : public MeshFacetVisitor +class MeshExport MeshSurfaceVisitor: public MeshFacetVisitor { public: - MeshSurfaceVisitor (MeshSurfaceSegment& segm, std::vector &indices); - bool AllowVisit (const MeshFacet& face, const MeshFacet&, - FacetIndex, unsigned long, unsigned short neighbourIndex) override; - bool Visit (const MeshFacet & face, const MeshFacet &, - FacetIndex ulFInd, unsigned long) override; + MeshSurfaceVisitor(MeshSurfaceSegment& segm, std::vector& indices); + bool AllowVisit(const MeshFacet& face, + const MeshFacet&, + FacetIndex, + unsigned long, + unsigned short neighbourIndex) override; + bool Visit(const MeshFacet& face, const MeshFacet&, FacetIndex ulFInd, unsigned long) override; protected: - std::vector &indices; + std::vector& indices; MeshSurfaceSegment& segm; }; class MeshExport MeshSegmentAlgorithm { public: - explicit MeshSegmentAlgorithm(const MeshKernel& kernel) : myKernel(kernel) {} + explicit MeshSegmentAlgorithm(const MeshKernel& kernel) + : myKernel(kernel) + {} void FindSegments(std::vector&); private: const MeshKernel& myKernel; }; -} // MeshCore +} // namespace MeshCore -#endif // MESHCORE_SEGMENTATION_H +#endif // MESHCORE_SEGMENTATION_H diff --git a/src/Mod/Mesh/App/Core/SetOperations.cpp b/src/Mod/Mesh/App/Core/SetOperations.cpp index 2c8671864e..2819b18b81 100644 --- a/src/Mod/Mesh/App/Core/SetOperations.cpp +++ b/src/Mod/Mesh/App/Core/SetOperations.cpp @@ -23,20 +23,20 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include +#include +#include #endif #include #include -#include "SetOperations.h" #include "Algorithm.h" #include "Builder.h" #include "Definitions.h" #include "Elements.h" #include "Grid.h" #include "Iterator.h" +#include "SetOperations.h" #include "Triangulation.h" #include "Visitor.h" @@ -45,458 +45,451 @@ using namespace Base; using namespace MeshCore; -SetOperations::SetOperations (const MeshKernel &cutMesh1, const MeshKernel &cutMesh2, MeshKernel &result, OperationType opType, float minDistanceToPoint) -: _cutMesh0(cutMesh1), - _cutMesh1(cutMesh2), - _resultMesh(result), - _operationType(opType), - _minDistanceToPoint(minDistanceToPoint) +SetOperations::SetOperations(const MeshKernel& cutMesh1, + const MeshKernel& cutMesh2, + MeshKernel& result, + OperationType opType, + float minDistanceToPoint) + : _cutMesh0(cutMesh1) + , _cutMesh1(cutMesh2) + , _resultMesh(result) + , _operationType(opType) + , _minDistanceToPoint(minDistanceToPoint) +{} + +void SetOperations::Do() { -} + _minDistanceToPoint = 0.000001f; + float saveMinMeshDistance = MeshDefinitions::_fMinPointDistance; + MeshDefinitions::SetMinPointDistance(0.000001f); -void SetOperations::Do () -{ - _minDistanceToPoint = 0.000001f; - float saveMinMeshDistance = MeshDefinitions::_fMinPointDistance; - MeshDefinitions::SetMinPointDistance(0.000001f); + // Base::Sequencer().start("set operation", 5); -// Base::Sequencer().start("set operation", 5); + // _builder.clear(); - // _builder.clear(); + // Base::Sequencer().next(); + std::set facetsCuttingEdge0, facetsCuttingEdge1; + Cut(facetsCuttingEdge0, facetsCuttingEdge1); - //Base::Sequencer().next(); - std::set facetsCuttingEdge0, facetsCuttingEdge1; - Cut(facetsCuttingEdge0, facetsCuttingEdge1); + // no intersection curve of the meshes found + if (facetsCuttingEdge0.empty() || facetsCuttingEdge1.empty()) { + switch (_operationType) { + case Union: { + _resultMesh = _cutMesh0; + _resultMesh.Merge(_cutMesh1); + } break; + case Intersect: { + _resultMesh.Clear(); + } break; + case Difference: + case Inner: + case Outer: { + _resultMesh = _cutMesh0; + } break; + default: { + _resultMesh.Clear(); + break; + } + } - // no intersection curve of the meshes found - if (facetsCuttingEdge0.empty() || facetsCuttingEdge1.empty()) - { - switch (_operationType) - { - case Union: - { - _resultMesh = _cutMesh0; - _resultMesh.Merge(_cutMesh1); - } break; - case Intersect: - { - _resultMesh.Clear(); - } break; - case Difference: - case Inner: - case Outer: - { - _resultMesh = _cutMesh0; - } break; - default: - { - _resultMesh.Clear(); - break; - } + MeshDefinitions::SetMinPointDistance(saveMinMeshDistance); + return; } + unsigned long i; + for (i = 0; i < _cutMesh0.CountFacets(); i++) { + if (facetsCuttingEdge0.find(i) == facetsCuttingEdge0.end()) { + _newMeshFacets[0].push_back(_cutMesh0.GetFacet(i)); + } + } + + for (i = 0; i < _cutMesh1.CountFacets(); i++) { + if (facetsCuttingEdge1.find(i) == facetsCuttingEdge1.end()) { + _newMeshFacets[1].push_back(_cutMesh1.GetFacet(i)); + } + } + + // Base::Sequencer().next(); + TriangulateMesh(_cutMesh0, 0); + + // Base::Sequencer().next(); + TriangulateMesh(_cutMesh1, 1); + + float mult0, mult1; + switch (_operationType) { + case Union: + mult0 = -1.0f; + mult1 = -1.0f; + break; + case Intersect: + mult0 = 1.0f; + mult1 = 1.0f; + break; + case Difference: + mult0 = -1.0f; + mult1 = 1.0f; + break; + case Inner: + mult0 = 1.0f; + mult1 = 0.0f; + break; + case Outer: + mult0 = -1.0f; + mult1 = 0.0f; + break; + default: + mult0 = 0.0f; + mult1 = 0.0f; + break; + } + + // Base::Sequencer().next(); + CollectFacets(0, mult0); + // Base::Sequencer().next(); + CollectFacets(1, mult1); + + std::vector facets; + + std::vector::iterator itf; + for (itf = _facetsOf[0].begin(); itf != _facetsOf[0].end(); ++itf) { + if (_operationType == Difference) { // toggle normal + std::swap(itf->_aclPoints[0], itf->_aclPoints[1]); + itf->CalcNormal(); + } + + facets.push_back(*itf); + } + + for (itf = _facetsOf[1].begin(); itf != _facetsOf[1].end(); ++itf) { + facets.push_back(*itf); + } + + _resultMesh = facets; + + // Base::Sequencer().stop(); + // _builder.saveToFile("c:/temp/vdbg.iv"); + MeshDefinitions::SetMinPointDistance(saveMinMeshDistance); - return; - } - - unsigned long i; - for (i = 0; i < _cutMesh0.CountFacets(); i++) - { - if (facetsCuttingEdge0.find(i) == facetsCuttingEdge0.end()) - _newMeshFacets[0].push_back(_cutMesh0.GetFacet(i)); - } - - for (i = 0; i < _cutMesh1.CountFacets(); i++) - { - if (facetsCuttingEdge1.find(i) == facetsCuttingEdge1.end()) - _newMeshFacets[1].push_back(_cutMesh1.GetFacet(i)); - } - - //Base::Sequencer().next(); - TriangulateMesh(_cutMesh0, 0); - - //Base::Sequencer().next(); - TriangulateMesh(_cutMesh1, 1); - - float mult0, mult1; - switch (_operationType) - { - case Union: mult0 = -1.0f; mult1 = -1.0f; break; - case Intersect: mult0 = 1.0f; mult1 = 1.0f; break; - case Difference: mult0 = -1.0f; mult1 = 1.0f; break; - case Inner: mult0 = 1.0f; mult1 = 0.0f; break; - case Outer: mult0 = -1.0f; mult1 = 0.0f; break; - default: mult0 = 0.0f; mult1 = 0.0f; break; - } - - //Base::Sequencer().next(); - CollectFacets(0, mult0); - //Base::Sequencer().next(); - CollectFacets(1, mult1); - - std::vector facets; - - std::vector::iterator itf; - for (itf = _facetsOf[0].begin(); itf != _facetsOf[0].end(); ++itf) - { - if (_operationType == Difference) - { // toggle normal - std::swap(itf->_aclPoints[0], itf->_aclPoints[1]); - itf->CalcNormal(); - } - - facets.push_back(*itf); - } - - for (itf = _facetsOf[1].begin(); itf != _facetsOf[1].end(); ++itf) - { - facets.push_back(*itf); - } - - _resultMesh = facets; - - //Base::Sequencer().stop(); - // _builder.saveToFile("c:/temp/vdbg.iv"); - - MeshDefinitions::SetMinPointDistance(saveMinMeshDistance); } -void SetOperations::Cut (std::set& facetsCuttingEdge0, std::set& facetsCuttingEdge1) +void SetOperations::Cut(std::set& facetsCuttingEdge0, + std::set& facetsCuttingEdge1) { - MeshFacetGrid grid1(_cutMesh0, 20); - MeshFacetGrid grid2(_cutMesh1, 20); + MeshFacetGrid grid1(_cutMesh0, 20); + MeshFacetGrid grid2(_cutMesh1, 20); - unsigned long ctGx1, ctGy1, ctGz1; - grid1.GetCtGrids(ctGx1, ctGy1, ctGz1); + unsigned long ctGx1, ctGy1, ctGz1; + grid1.GetCtGrids(ctGx1, ctGy1, ctGz1); - unsigned long gx1; - for (gx1 = 0; gx1 < ctGx1; gx1++) - { - unsigned long gy1; - for (gy1 = 0; gy1 < ctGy1; gy1++) - { - unsigned long gz1; - for (gz1 = 0; gz1 < ctGz1; gz1++) - { - if (grid1.GetCtElements(gx1, gy1, gz1) > 0) - { - std::vector vecFacets2; - grid2.Inside(grid1.GetBoundBox(gx1, gy1, gz1), vecFacets2); + unsigned long gx1; + for (gx1 = 0; gx1 < ctGx1; gx1++) { + unsigned long gy1; + for (gy1 = 0; gy1 < ctGy1; gy1++) { + unsigned long gz1; + for (gz1 = 0; gz1 < ctGz1; gz1++) { + if (grid1.GetCtElements(gx1, gy1, gz1) > 0) { + std::vector vecFacets2; + grid2.Inside(grid1.GetBoundBox(gx1, gy1, gz1), vecFacets2); - if (!vecFacets2.empty()) - { - std::set vecFacets1; - grid1.GetElements(gx1, gy1, gz1, vecFacets1); + if (!vecFacets2.empty()) { + std::set vecFacets1; + grid1.GetElements(gx1, gy1, gz1, vecFacets1); - std::set::iterator it1; - for (it1 = vecFacets1.begin(); it1 != vecFacets1.end(); ++it1) - { - FacetIndex fidx1 = *it1; - MeshGeomFacet f1 = _cutMesh0.GetFacet(*it1); + std::set::iterator it1; + for (it1 = vecFacets1.begin(); it1 != vecFacets1.end(); ++it1) { + FacetIndex fidx1 = *it1; + MeshGeomFacet f1 = _cutMesh0.GetFacet(*it1); - std::vector::iterator it2; - for (it2 = vecFacets2.begin(); it2 != vecFacets2.end(); ++it2) - { - FacetIndex fidx2 = *it2; - MeshGeomFacet f2 = _cutMesh1.GetFacet(fidx2); + std::vector::iterator it2; + for (it2 = vecFacets2.begin(); it2 != vecFacets2.end(); ++it2) { + FacetIndex fidx2 = *it2; + MeshGeomFacet f2 = _cutMesh1.GetFacet(fidx2); - MeshPoint p0, p1; + MeshPoint p0, p1; - int isect = f1.IntersectWithFacet(f2, p0, p1); - if (isect > 0) - { - // optimize cut line if distance to nearest point is too small - float minDist1 = _minDistanceToPoint, minDist2 = _minDistanceToPoint; - MeshPoint np0 = p0, np1 = p1; - int i; - for (i = 0; i < 3; i++) - { - float d1 = (f1._aclPoints[i] - p0).Length(); - float d2 = (f1._aclPoints[i] - p1).Length(); - if (d1 < minDist1) - { - minDist1 = d1; - np0 = f1._aclPoints[i]; - } - if (d2 < minDist2) - { - minDist2 = d2; - p1 = f1._aclPoints[i]; - } - } // for (int i = 0; i < 3; i++) + int isect = f1.IntersectWithFacet(f2, p0, p1); + if (isect > 0) { + // optimize cut line if distance to nearest point is too small + float minDist1 = _minDistanceToPoint, + minDist2 = _minDistanceToPoint; + MeshPoint np0 = p0, np1 = p1; + int i; + for (i = 0; i < 3; i++) { + float d1 = (f1._aclPoints[i] - p0).Length(); + float d2 = (f1._aclPoints[i] - p1).Length(); + if (d1 < minDist1) { + minDist1 = d1; + np0 = f1._aclPoints[i]; + } + if (d2 < minDist2) { + minDist2 = d2; + p1 = f1._aclPoints[i]; + } + } // for (int i = 0; i < 3; i++) - // optimize cut line if distance to nearest point is too small - for (i = 0; i < 3; i++) - { - float d1 = (f2._aclPoints[i] - p0).Length(); - float d2 = (f2._aclPoints[i] - p1).Length(); - if (d1 < minDist1) - { - minDist1 = d1; - np0 = f2._aclPoints[i]; - } - if (d2 < minDist2) - { - minDist2 = d2; - np1 = f2._aclPoints[i]; - } - } // for (int i = 0; i < 3; i++) + // optimize cut line if distance to nearest point is too small + for (i = 0; i < 3; i++) { + float d1 = (f2._aclPoints[i] - p0).Length(); + float d2 = (f2._aclPoints[i] - p1).Length(); + if (d1 < minDist1) { + minDist1 = d1; + np0 = f2._aclPoints[i]; + } + if (d2 < minDist2) { + minDist2 = d2; + np1 = f2._aclPoints[i]; + } + } // for (int i = 0; i < 3; i++) - MeshPoint mp0 = np0; - MeshPoint mp1 = np1; + MeshPoint mp0 = np0; + MeshPoint mp1 = np1; - if (mp0 != mp1) - { - facetsCuttingEdge0.insert(fidx1); - facetsCuttingEdge1.insert(fidx2); + if (mp0 != mp1) { + facetsCuttingEdge0.insert(fidx1); + facetsCuttingEdge1.insert(fidx2); - _cutPoints.insert(mp0); - _cutPoints.insert(mp1); + _cutPoints.insert(mp0); + _cutPoints.insert(mp1); - std::pair::iterator, bool> pit0 = _cutPoints.insert(mp0); - std::pair::iterator, bool> pit1 = _cutPoints.insert(mp1); + std::pair::iterator, bool> pit0 = + _cutPoints.insert(mp0); + std::pair::iterator, bool> pit1 = + _cutPoints.insert(mp1); - _edges[Edge(mp0, mp1)] = EdgeInfo(); + _edges[Edge(mp0, mp1)] = EdgeInfo(); - _facet2points[0][fidx1].push_back(pit0.first); - _facet2points[0][fidx1].push_back(pit1.first); - _facet2points[1][fidx2].push_back(pit0.first); - _facet2points[1][fidx2].push_back(pit1.first); + _facet2points[0][fidx1].push_back(pit0.first); + _facet2points[0][fidx1].push_back(pit1.first); + _facet2points[1][fidx2].push_back(pit0.first); + _facet2points[1][fidx2].push_back(pit1.first); + } + else { + std::pair::iterator, bool> pit = + _cutPoints.insert(mp0); - } - else - { - std::pair::iterator, bool> pit = _cutPoints.insert(mp0); + // do not insert a facet when only one corner point cuts the + // edge if (!((mp0 == f1._aclPoints[0]) || (mp0 == + // f1._aclPoints[1]) || (mp0 == f1._aclPoints[2]))) + { + facetsCuttingEdge0.insert(fidx1); + _facet2points[0][fidx1].push_back(pit.first); + } - // do not insert a facet when only one corner point cuts the edge - // if (!((mp0 == f1._aclPoints[0]) || (mp0 == f1._aclPoints[1]) || (mp0 == f1._aclPoints[2]))) - { - facetsCuttingEdge0.insert(fidx1); - _facet2points[0][fidx1].push_back(pit.first); - } + // if (!((mp0 == f2._aclPoints[0]) || (mp0 == + // f2._aclPoints[1]) || (mp0 == f2._aclPoints[2]))) + { + facetsCuttingEdge1.insert(fidx2); + _facet2points[1][fidx2].push_back(pit.first); + } + } - // if (!((mp0 == f2._aclPoints[0]) || (mp0 == f2._aclPoints[1]) || (mp0 == f2._aclPoints[2]))) - { - facetsCuttingEdge1.insert(fidx2); - _facet2points[1][fidx2].push_back(pit.first); - } - } - - } // if (f1.IntersectWithFacet(f2, p0, p1)) - } // for (it2 = vecFacets2.begin(); it2 != vecFacets2.end(); ++it2) - } // for (it1 = vecFacets1.begin(); it1 != vecFacets1.end(); ++it1) - } // if (vecFacets2.size() > 0) - } // if (grid1.GetCtElements(gx1, gy1, gz1) > 0) - } // for (gz1 = 0; gz1 < ctGz1; gz1++) - } // for (gy1 = 0; gy1 < ctGy1; gy1++) - } // for (gx1 = 0; gx1 < ctGx1; gx1++) + } // if (f1.IntersectWithFacet(f2, p0, p1)) + } // for (it2 = vecFacets2.begin(); it2 != vecFacets2.end(); ++it2) + } // for (it1 = vecFacets1.begin(); it1 != vecFacets1.end(); ++it1) + } // if (vecFacets2.size() > 0) + } // if (grid1.GetCtElements(gx1, gy1, gz1) > 0) + } // for (gz1 = 0; gz1 < ctGz1; gz1++) + } // for (gy1 = 0; gy1 < ctGy1; gy1++) + } // for (gx1 = 0; gx1 < ctGx1; gx1++) } -void SetOperations::TriangulateMesh (const MeshKernel &cutMesh, int side) +void SetOperations::TriangulateMesh(const MeshKernel& cutMesh, int side) { - // Triangulate Mesh - std::map::iterator> >::iterator it1; - for (it1 = _facet2points[side].begin(); it1 != _facet2points[side].end(); ++it1) - { - std::vector points; - std::set pointsSet; + // Triangulate Mesh + std::map::iterator>>::iterator it1; + for (it1 = _facet2points[side].begin(); it1 != _facet2points[side].end(); ++it1) { + std::vector points; + std::set pointsSet; - FacetIndex fidx = it1->first; - MeshGeomFacet f = cutMesh.GetFacet(fidx); + FacetIndex fidx = it1->first; + MeshGeomFacet f = cutMesh.GetFacet(fidx); - //if (side == 1) - // _builder.addSingleTriangle(f._aclPoints[0], f._aclPoints[1], f._aclPoints[2], 3, 0, 1, 1); + // if (side == 1) + // _builder.addSingleTriangle(f._aclPoints[0], f._aclPoints[1], f._aclPoints[2], 3, 0, + // 1, 1); - // facet corner points - //const MeshFacet& mf = cutMesh._aclFacetArray[fidx]; - int i; - for (i = 0; i < 3; i++) - { - pointsSet.insert(f._aclPoints[i]); - points.push_back(f._aclPoints[i]); - } - - // triangulated facets - std::list::iterator>::iterator it2; - for (it2 = it1->second.begin(); it2 != it1->second.end(); ++it2) - { - if (pointsSet.find(*(*it2)) == pointsSet.end()) - { - pointsSet.insert(*(*it2)); - points.push_back(*(*it2)); - } - - } - - Vector3f normal = f.GetNormal(); - Vector3f base = points[0]; - Vector3f dirX = points[1] - points[0]; - dirX.Normalize(); - Vector3f dirY = dirX % normal; - - // project points to 2D plane - std::vector::iterator it; - std::vector vertices; - for (it = points.begin(); it != points.end(); ++it) - { - Vector3f pv = *it; - pv.TransformToCoordinateSystem(base, dirX, dirY); - vertices.push_back(pv); - } - - DelaunayTriangulator tria; - tria.SetPolygon(vertices); - tria.TriangulatePolygon(); - - std::vector facets = tria.GetFacets(); - for (auto & it : facets) - { - if ((it._aulPoints[0] == it._aulPoints[1]) || - (it._aulPoints[1] == it._aulPoints[2]) || - (it._aulPoints[2] == it._aulPoints[0])) - { // two same triangle corner points - continue; - } - - MeshGeomFacet facet(points[it._aulPoints[0]], - points[it._aulPoints[1]], - points[it._aulPoints[2]]); - - //if (side == 1) - // _builder.addSingleTriangle(facet._aclPoints[0], facet._aclPoints[1], facet._aclPoints[2], true, 3, 0, 1, 1); - - //if (facet.Area() < 0.0001f) - //{ // too small facet - // continue; - //} - - float dist0 = facet._aclPoints[0].DistanceToLine - (facet._aclPoints[1],facet._aclPoints[1] - facet._aclPoints[2]); - float dist1 = facet._aclPoints[1].DistanceToLine - (facet._aclPoints[0],facet._aclPoints[0] - facet._aclPoints[2]); - float dist2 = facet._aclPoints[2].DistanceToLine - (facet._aclPoints[0],facet._aclPoints[0] - facet._aclPoints[1]); - - if ((dist0 < _minDistanceToPoint) || - (dist1 < _minDistanceToPoint) || - (dist2 < _minDistanceToPoint)) - { - continue; - } - - //dist0 = (facet._aclPoints[0] - facet._aclPoints[1]).Length(); - //dist1 = (facet._aclPoints[1] - facet._aclPoints[2]).Length(); - //dist2 = (facet._aclPoints[2] - facet._aclPoints[3]).Length(); - - //if ((dist0 < _minDistanceToPoint) || (dist1 < _minDistanceToPoint) || (dist2 < _minDistanceToPoint)) - //{ - // continue; - //} - - facet.CalcNormal(); - if ((facet.GetNormal() * f.GetNormal()) < 0.0f) - { // adjust normal - std::swap(facet._aclPoints[0], facet._aclPoints[1]); - facet.CalcNormal(); - } - - - int j; - for (j = 0; j < 3; j++) - { - std::map::iterator eit = _edges.find(Edge(facet._aclPoints[j], facet._aclPoints[(j+1)%3])); - - if (eit != _edges.end()) - { - - if (eit->second.fcounter[side] < 2) - { - //if (side == 0) - // _builder.addSingleTriangle(facet._aclPoints[0], facet._aclPoints[1], facet._aclPoints[2], true, 3, 0, 1, 1); - - eit->second.facet[side] = fidx; - eit->second.facets[side][eit->second.fcounter[side]] = facet; - eit->second.fcounter[side]++; - facet.SetFlag(MeshFacet::MARKED); // set all facets connected to an edge: MARKED - - } + // facet corner points + // const MeshFacet& mf = cutMesh._aclFacetArray[fidx]; + int i; + for (i = 0; i < 3; i++) { + pointsSet.insert(f._aclPoints[i]); + points.push_back(f._aclPoints[i]); } - } - _newMeshFacets[side].push_back(facet); + // triangulated facets + std::list::iterator>::iterator it2; + for (it2 = it1->second.begin(); it2 != it1->second.end(); ++it2) { + if (pointsSet.find(*(*it2)) == pointsSet.end()) { + pointsSet.insert(*(*it2)); + points.push_back(*(*it2)); + } + } - } // for (i = 0; i < (out->numberoftriangles * 3); i += 3) - } // for (it1 = _facet2points[side].begin(); it1 != _facet2points[side].end(); ++it1) + Vector3f normal = f.GetNormal(); + Vector3f base = points[0]; + Vector3f dirX = points[1] - points[0]; + dirX.Normalize(); + Vector3f dirY = dirX % normal; + + // project points to 2D plane + std::vector::iterator it; + std::vector vertices; + for (it = points.begin(); it != points.end(); ++it) { + Vector3f pv = *it; + pv.TransformToCoordinateSystem(base, dirX, dirY); + vertices.push_back(pv); + } + + DelaunayTriangulator tria; + tria.SetPolygon(vertices); + tria.TriangulatePolygon(); + + std::vector facets = tria.GetFacets(); + for (auto& it : facets) { + if ((it._aulPoints[0] == it._aulPoints[1]) || (it._aulPoints[1] == it._aulPoints[2]) + || (it._aulPoints[2] == it._aulPoints[0])) { // two same triangle corner points + continue; + } + + MeshGeomFacet facet(points[it._aulPoints[0]], + points[it._aulPoints[1]], + points[it._aulPoints[2]]); + + // if (side == 1) + // _builder.addSingleTriangle(facet._aclPoints[0], facet._aclPoints[1], + // facet._aclPoints[2], true, 3, 0, 1, 1); + + // if (facet.Area() < 0.0001f) + //{ // too small facet + // continue; + // } + + float dist0 = + facet._aclPoints[0].DistanceToLine(facet._aclPoints[1], + facet._aclPoints[1] - facet._aclPoints[2]); + float dist1 = + facet._aclPoints[1].DistanceToLine(facet._aclPoints[0], + facet._aclPoints[0] - facet._aclPoints[2]); + float dist2 = + facet._aclPoints[2].DistanceToLine(facet._aclPoints[0], + facet._aclPoints[0] - facet._aclPoints[1]); + + if ((dist0 < _minDistanceToPoint) || (dist1 < _minDistanceToPoint) + || (dist2 < _minDistanceToPoint)) { + continue; + } + + // dist0 = (facet._aclPoints[0] - facet._aclPoints[1]).Length(); + // dist1 = (facet._aclPoints[1] - facet._aclPoints[2]).Length(); + // dist2 = (facet._aclPoints[2] - facet._aclPoints[3]).Length(); + + // if ((dist0 < _minDistanceToPoint) || (dist1 < _minDistanceToPoint) || (dist2 < + // _minDistanceToPoint)) + //{ + // continue; + // } + + facet.CalcNormal(); + if ((facet.GetNormal() * f.GetNormal()) < 0.0f) { // adjust normal + std::swap(facet._aclPoints[0], facet._aclPoints[1]); + facet.CalcNormal(); + } + + + int j; + for (j = 0; j < 3; j++) { + std::map::iterator eit = + _edges.find(Edge(facet._aclPoints[j], facet._aclPoints[(j + 1) % 3])); + + if (eit != _edges.end()) { + + if (eit->second.fcounter[side] < 2) { + // if (side == 0) + // _builder.addSingleTriangle(facet._aclPoints[0], facet._aclPoints[1], + // facet._aclPoints[2], true, 3, 0, 1, 1); + + eit->second.facet[side] = fidx; + eit->second.facets[side][eit->second.fcounter[side]] = facet; + eit->second.fcounter[side]++; + facet.SetFlag( + MeshFacet::MARKED); // set all facets connected to an edge: MARKED + } + } + } + + _newMeshFacets[side].push_back(facet); + + } // for (i = 0; i < (out->numberoftriangles * 3); i += 3) + } // for (it1 = _facet2points[side].begin(); it1 != _facet2points[side].end(); ++it1) } -void SetOperations::CollectFacets (int side, float mult) +void SetOperations::CollectFacets(int side, float mult) { - // float distSave = MeshDefinitions::_fMinPointDistance; - //MeshDefinitions::SetMinPointDistance(1.0e-4f); + // float distSave = MeshDefinitions::_fMinPointDistance; + // MeshDefinitions::SetMinPointDistance(1.0e-4f); - MeshKernel mesh; - MeshBuilder mb(mesh); - mb.Initialize(_newMeshFacets[side].size()); - std::vector::iterator it; - for (it = _newMeshFacets[side].begin(); it != _newMeshFacets[side].end(); ++it) - { - //if (it->IsFlag(MeshFacet::MARKED)) - //{ - // _builder.addSingleTriangle(it->_aclPoints[0], it->_aclPoints[1], it->_aclPoints[2], true, 3.0, 0.0, 1.0, 1.0); - //} - mb.AddFacet(*it, true); - } - mb.Finish(); - - MeshAlgorithm algo(mesh); - algo.ResetFacetFlag(static_cast(MeshFacet::VISIT | MeshFacet::TMP0)); - - // bool hasFacetsNotVisited = true; // until facets not visited - // search for facet not visited - MeshFacetArray::_TConstIterator itf; - const MeshFacetArray& rFacets = mesh.GetFacets(); - for (itf = rFacets.begin(); itf != rFacets.end(); ++itf) - { - if (!itf->IsFlag(MeshFacet::VISIT)) - { // Facet found, visit neighbours - std::vector facets; - facets.push_back(itf - rFacets.begin()); // add seed facet - CollectFacetVisitor visitor(mesh, facets, _edges, side, mult, _builder); - mesh.VisitNeighbourFacets(visitor, itf - rFacets.begin()); - - if (visitor._addFacets == 0) - { // mark all facets to add it to the result - algo.SetFacetsFlag(facets, MeshFacet::TMP0); - } + MeshKernel mesh; + MeshBuilder mb(mesh); + mb.Initialize(_newMeshFacets[side].size()); + std::vector::iterator it; + for (it = _newMeshFacets[side].begin(); it != _newMeshFacets[side].end(); ++it) { + // if (it->IsFlag(MeshFacet::MARKED)) + //{ + // _builder.addSingleTriangle(it->_aclPoints[0], it->_aclPoints[1], it->_aclPoints[2], + // true, 3.0, 0.0, 1.0, 1.0); + // } + mb.AddFacet(*it, true); } - } + mb.Finish(); - // add all facets to the result vector - for (itf = rFacets.begin(); itf != rFacets.end(); ++itf) - { - if (itf->IsFlag(MeshFacet::TMP0)) - { - _facetsOf[side].push_back(mesh.GetFacet(*itf)); + MeshAlgorithm algo(mesh); + algo.ResetFacetFlag(static_cast(MeshFacet::VISIT | MeshFacet::TMP0)); + + // bool hasFacetsNotVisited = true; // until facets not visited + // search for facet not visited + MeshFacetArray::_TConstIterator itf; + const MeshFacetArray& rFacets = mesh.GetFacets(); + for (itf = rFacets.begin(); itf != rFacets.end(); ++itf) { + if (!itf->IsFlag(MeshFacet::VISIT)) { // Facet found, visit neighbours + std::vector facets; + facets.push_back(itf - rFacets.begin()); // add seed facet + CollectFacetVisitor visitor(mesh, facets, _edges, side, mult, _builder); + mesh.VisitNeighbourFacets(visitor, itf - rFacets.begin()); + + if (visitor._addFacets == 0) { // mark all facets to add it to the result + algo.SetFacetsFlag(facets, MeshFacet::TMP0); + } + } } - } - // MeshDefinitions::SetMinPointDistance(distSave); + // add all facets to the result vector + for (itf = rFacets.begin(); itf != rFacets.end(); ++itf) { + if (itf->IsFlag(MeshFacet::TMP0)) { + _facetsOf[side].push_back(mesh.GetFacet(*itf)); + } + } + + // MeshDefinitions::SetMinPointDistance(distSave); } -SetOperations::CollectFacetVisitor::CollectFacetVisitor (const MeshKernel& mesh, std::vector& facets, - std::map& edges, int side, float mult, - Base::Builder3D& builder) - : _facets(facets) - , _mesh(mesh) - , _edges(edges) - , _side(side) - , _mult(mult) - , _builder(builder) -{ -} +SetOperations::CollectFacetVisitor::CollectFacetVisitor(const MeshKernel& mesh, + std::vector& facets, + std::map& edges, + int side, + float mult, + Base::Builder3D& builder) + : _facets(facets) + , _mesh(mesh) + , _edges(edges) + , _side(side) + , _mult(mult) + , _builder(builder) +{} -bool SetOperations::CollectFacetVisitor::Visit (const MeshFacet &rclFacet, const MeshFacet &rclFrom, - FacetIndex ulFInd, unsigned long ulLevel) +bool SetOperations::CollectFacetVisitor::Visit(const MeshFacet& rclFacet, + const MeshFacet& rclFrom, + FacetIndex ulFInd, + unsigned long ulLevel) { (void)rclFacet; (void)rclFrom; @@ -505,16 +498,19 @@ bool SetOperations::CollectFacetVisitor::Visit (const MeshFacet &rclFacet, const return true; } -//static int matchCounter = 0; -bool SetOperations::CollectFacetVisitor::AllowVisit (const MeshFacet& rclFacet, const MeshFacet& rclFrom, - FacetIndex ulFInd, unsigned long ulLevel, - unsigned short neighbourIndex) +// static int matchCounter = 0; +bool SetOperations::CollectFacetVisitor::AllowVisit(const MeshFacet& rclFacet, + const MeshFacet& rclFrom, + FacetIndex ulFInd, + unsigned long ulLevel, + unsigned short neighbourIndex) { (void)ulFInd; (void)ulLevel; if (rclFacet.IsFlag(MeshFacet::MARKED) && rclFrom.IsFlag(MeshFacet::MARKED)) { // facet connected to an edge - PointIndex pt0 = rclFrom._aulPoints[neighbourIndex], pt1 = rclFrom._aulPoints[(neighbourIndex+1)%3]; + PointIndex pt0 = rclFrom._aulPoints[neighbourIndex], + pt1 = rclFrom._aulPoints[(neighbourIndex + 1) % 3]; Edge edge(_mesh.GetPoint(pt0), _mesh.GetPoint(pt1)); std::map::iterator it = _edges.find(edge); @@ -522,35 +518,46 @@ bool SetOperations::CollectFacetVisitor::AllowVisit (const MeshFacet& rclFacet, if (it != _edges.end()) { if (_addFacets == -1) { // determine if the facets should add or not only once - MeshGeomFacet facet = _mesh.GetFacet(rclFrom); // triangulated facet - MeshGeomFacet facetOther = it->second.facets[1-_side][0]; // triangulated facet from same edge and other mesh + MeshGeomFacet facet = _mesh.GetFacet(rclFrom); // triangulated facet + MeshGeomFacet facetOther = + it->second + .facets[1 - _side][0]; // triangulated facet from same edge and other mesh Vector3f normalOther = facetOther.GetNormal(); - //Vector3f normal = facet.GetNormal(); + // Vector3f normal = facet.GetNormal(); Vector3f edgeDir = it->first.pt1 - it->first.pt2; Vector3f ocDir = (edgeDir % (facet.GetGravityPoint() - it->first.pt1)) % edgeDir; ocDir.Normalize(); - Vector3f ocDirOther = (edgeDir % (facetOther.GetGravityPoint() - it->first.pt1)) % edgeDir; + Vector3f ocDirOther = + (edgeDir % (facetOther.GetGravityPoint() - it->first.pt1)) % edgeDir; ocDirOther.Normalize(); - //Vector3f dir = ocDir % normal; - //Vector3f dirOther = ocDirOther % normalOther; + // Vector3f dir = ocDir % normal; + // Vector3f dirOther = ocDirOther % normalOther; bool match = ((ocDir * normalOther) * _mult) < 0.0f; - //if (matchCounter == 1) + // if (matchCounter == 1) //{ - // // _builder.addSingleArrow(it->second.pt1, it->second.pt1 + edgeDir, 3, 0.0, 1.0, 0.0); + // // _builder.addSingleArrow(it->second.pt1, it->second.pt1 + edgeDir, 3, + // 0.0, 1.0, 0.0); - // _builder.addSingleTriangle(facet._aclPoints[0], facet._aclPoints[1], facet._aclPoints[2], true, 3.0, 1.0, 0.0, 0.0); - // // _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + ocDir, 3, 1.0, 0.0, 0.0); - // _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + normal, 3, 1.0, 0.5, 0.0); - // // _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + dir, 3, 1.0, 1.0, 0.0); + // _builder.addSingleTriangle(facet._aclPoints[0], facet._aclPoints[1], + // facet._aclPoints[2], true, 3.0, 1.0, 0.0, 0.0); + // // _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + + // ocDir, 3, 1.0, 0.0, 0.0); _builder.addSingleArrow(facet.GetGravityPoint(), + // facet.GetGravityPoint() + normal, 3, 1.0, 0.5, 0.0); + // // _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + + // dir, 3, 1.0, 1.0, 0.0); - // _builder.addSingleTriangle(facetOther._aclPoints[0], facetOther._aclPoints[1], facetOther._aclPoints[2], true, 3.0, 0.0, 0.0, 1.0); - // // _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + ocDirOther, 3, 0.0, 0.0, 1.0); - // _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + normalOther, 3, 0.0, 0.5, 1.0); - // // _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + dirOther, 3, 0.0, 1.0, 1.0); + // _builder.addSingleTriangle(facetOther._aclPoints[0], facetOther._aclPoints[1], + // facetOther._aclPoints[2], true, 3.0, 0.0, 0.0, 1.0); + // // _builder.addSingleArrow(facetOther.GetGravityPoint(), + // facetOther.GetGravityPoint() + ocDirOther, 3, 0.0, 0.0, 1.0); + // _builder.addSingleArrow(facetOther.GetGravityPoint(), + // facetOther.GetGravityPoint() + normalOther, 3, 0.0, 0.5, 1.0); + // // _builder.addSingleArrow(facetOther.GetGravityPoint(), + // facetOther.GetGravityPoint() + dirOther, 3, 0.0, 1.0, 1.0); //} @@ -558,34 +565,35 @@ bool SetOperations::CollectFacetVisitor::AllowVisit (const MeshFacet& rclFacet, // bool match = scalar > 0.0f; - //MeshPoint pt0 = it->first.pt1; - //MeshPoint pt1 = it->first.pt2; + // MeshPoint pt0 = it->first.pt1; + // MeshPoint pt1 = it->first.pt2; - //int i, n0 = -1, n1 = -1, m0 = -1, m1 = -1; - //for (i = 0; i < 3; i++) + // int i, n0 = -1, n1 = -1, m0 = -1, m1 = -1; + // for (i = 0; i < 3; i++) //{ - // if ((n0 == -1) && (facet._aclPoints[i] == pt0)) - // n0 = i; - // if ((n1 == -1) && (facet._aclPoints[i] == pt1)) - // n1 = i; - // if ((m0 == -1) && (facetOther._aclPoints[i] == pt0)) - // m0 = i; - // if ((m1 == -1) && (facetOther._aclPoints[i] == pt1)) - // m1 = i; - //} + // if ((n0 == -1) && (facet._aclPoints[i] == pt0)) + // n0 = i; + // if ((n1 == -1) && (facet._aclPoints[i] == pt1)) + // n1 = i; + // if ((m0 == -1) && (facetOther._aclPoints[i] == pt0)) + // m0 = i; + // if ((m1 == -1) && (facetOther._aclPoints[i] == pt1)) + // m1 = i; + // } - //if ((n0 != -1) && (n1 != -1) && (m0 != -1) && (m1 != -1)) + // if ((n0 != -1) && (n1 != -1) && (m0 != -1) && (m1 != -1)) //{ - // bool orient_n = n1 > n0; - // bool orient_m = m1 > m0; + // bool orient_n = n1 > n0; + // bool orient_m = m1 > m0; // Vector3f dirN = facet._aclPoints[n1] - facet._aclPoints[n0]; // Vector3f dirM = facetOther._aclPoints[m1] - facetOther._aclPoints[m0]; // if (matchCounter == 1) // { - // _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + dirN, 3, 1.0, 1.0, 0.0); - // _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + dirM, 3, 0.0, 1.0, 1.0); + // _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + + // dirN, 3, 1.0, 1.0, 0.0); _builder.addSingleArrow(facetOther.GetGravityPoint(), + // facetOther.GetGravityPoint() + dirM, 3, 0.0, 1.0, 1.0); // } // if (_mult > 0.0) @@ -594,12 +602,14 @@ bool SetOperations::CollectFacetVisitor::AllowVisit (const MeshFacet& rclFacet, // match = orient_n != orient_m; //} - if (match) + if (match) { _addFacets = 0; - else + } + else { _addFacets = 1; + } - //matchCounter++; + // matchCounter++; } return false; @@ -615,11 +625,13 @@ bool MeshIntersection::hasIntersection() const { Base::BoundBox3f bbox1 = kernel1.GetBoundBox(); Base::BoundBox3f bbox2 = kernel2.GetBoundBox(); - if (!(bbox1 && bbox2)) + if (!(bbox1 && bbox2)) { return false; + } - if (testIntersection(kernel1, kernel2)) + if (testIntersection(kernel1, kernel2)) { return true; + } return false; } @@ -679,8 +691,7 @@ void MeshIntersection::getIntersection(std::list& intsc } } -bool MeshIntersection::testIntersection(const MeshKernel& k1, - const MeshKernel& k2) +bool MeshIntersection::testIntersection(const MeshKernel& k1, const MeshKernel& k2) { // Contains bounding boxes for every facet of 'k1' std::vector boxes1; @@ -730,8 +741,9 @@ bool MeshIntersection::testIntersection(const MeshKernel& k1, return false; } -void MeshIntersection::connectLines(bool onlyclosed, const std::list& rdata, - std::list< std::list >& lines) +void MeshIntersection::connectLines(bool onlyclosed, + const std::list& rdata, + std::list>& lines) { float fMinEps = minDistance * minDistance; @@ -744,10 +756,10 @@ void MeshIntersection::connectLines(bool onlyclosed, const std::listf1; front.f2 = data.begin()->f2; - front.p = data.begin()->p1; // current start point of the polyline + front.p = data.begin()->p1; // current start point of the polyline back.f1 = data.begin()->f1; back.f2 = data.begin()->f2; - back.p = data.begin()->p2; // current end point of the polyline + back.p = data.begin()->p2; // current end point of the polyline newPoly.push_back(front); newPoly.push_back(back); data.erase(data.begin()); @@ -756,33 +768,33 @@ void MeshIntersection::connectLines(bool onlyclosed, const std::list::iterator pFront, pEnd; bool bFoundLine; do { - float fFrontMin = fMinEps, fEndMin = fMinEps; - bool bFrontFirst=false, bEndFirst=false; + float fFrontMin = fMinEps, fEndMin = fMinEps; + bool bFrontFirst = false, bEndFirst = false; pFront = data.end(); - pEnd = data.end(); + pEnd = data.end(); bFoundLine = false; for (pF = data.begin(); pF != data.end(); ++pF) { if (Base::DistanceP2(front.p, pF->p1) < fFrontMin) { - fFrontMin = Base::DistanceP2(front.p, pF->p1); - pFront = pF; + fFrontMin = Base::DistanceP2(front.p, pF->p1); + pFront = pF; bFrontFirst = true; } else if (Base::DistanceP2(back.p, pF->p1) < fEndMin) { - fEndMin = Base::DistanceP2(back.p, pF->p1); - pEnd = pF; - bEndFirst = true; + fEndMin = Base::DistanceP2(back.p, pF->p1); + pEnd = pF; + bEndFirst = true; } else if (Base::DistanceP2(front.p, pF->p2) < fFrontMin) { - fFrontMin = Base::DistanceP2(front.p, pF->p2); - pFront = pF; + fFrontMin = Base::DistanceP2(front.p, pF->p2); + pFront = pF; bFrontFirst = false; } else if (Base::DistanceP2(back.p, pF->p2) < fEndMin) { - fEndMin = Base::DistanceP2(back.p, pF->p2); - pEnd = pF; - bEndFirst = false; + fEndMin = Base::DistanceP2(back.p, pF->p2); + pEnd = pF; + bEndFirst = false; } if (fFrontMin == 0.0f || fEndMin == 0.0f) { @@ -825,12 +837,13 @@ void MeshIntersection::connectLines(bool onlyclosed, const std::list 2 && Base::DistanceP2(newPoly.front().p, newPoly.back().p) < fMinEps) + if (newPoly.size() > 2 + && Base::DistanceP2(newPoly.front().p, newPoly.back().p) < fMinEps) { lines.push_back(newPoly); + } } else { lines.push_back(newPoly); diff --git a/src/Mod/Mesh/App/Core/SetOperations.h b/src/Mod/Mesh/App/Core/SetOperations.h index 24593a44b4..bd7054fe4f 100644 --- a/src/Mod/Mesh/App/Core/SetOperations.h +++ b/src/Mod/Mesh/App/Core/SetOperations.h @@ -53,130 +53,153 @@ class MeshFacetIterator; class MeshExport SetOperations { public: - enum OperationType { Union, Intersect, Difference, Inner, Outer }; + enum OperationType + { + Union, + Intersect, + Difference, + Inner, + Outer + }; - /// Construction - SetOperations (const MeshKernel &cutMesh1, const MeshKernel &cutMesh2, MeshKernel &result, OperationType opType, float minDistanceToPoint = 1e-5f); + /// Construction + SetOperations(const MeshKernel& cutMesh1, + const MeshKernel& cutMesh2, + MeshKernel& result, + OperationType opType, + float minDistanceToPoint = 1e-5f); public: - - /** Cut this mesh with another one. The result is a list of polylines - * If the distance of the polyline to one of the points is less than minDistanceToPoint the polyline goes direct to the point - */ - void Do (); + /** Cut this mesh with another one. The result is a list of polylines + * If the distance of the polyline to one of the points is less than minDistanceToPoint the + * polyline goes direct to the point + */ + void Do(); protected: - const MeshKernel &_cutMesh0; /** Mesh for set operations source 1 */ - const MeshKernel &_cutMesh1; /** Mesh for set operations source 2 */ - MeshKernel &_resultMesh; /** Result mesh */ - OperationType _operationType; /** Set Operation Type */ - float _minDistanceToPoint; /** Minimal distance to facet corner points */ + const MeshKernel& _cutMesh0; /** Mesh for set operations source 1 */ + const MeshKernel& _cutMesh1; /** Mesh for set operations source 2 */ + MeshKernel& _resultMesh; /** Result mesh */ + OperationType _operationType; /** Set Operation Type */ + float _minDistanceToPoint; /** Minimal distance to facet corner points */ private: - // Helper class cutting edge to its two attached facets - class Edge - { + // Helper class cutting edge to its two attached facets + class Edge + { public: - MeshPoint pt1, pt2; // edge + MeshPoint pt1, pt2; // edge - Edge () = default; + Edge() = default; - Edge (MeshPoint p1, MeshPoint p2) - { - if (p1 < p2) + Edge(MeshPoint p1, MeshPoint p2) { - pt1 = p1; - pt2 = p2; + if (p1 < p2) { + pt1 = p1; + pt2 = p2; + } + else { + pt2 = p1; + pt1 = p2; + } } - else + + bool operator==(const Edge& edge) const { - pt2 = p1; - pt1 = p2; + return (pt1 == edge.pt1) && (pt2 == edge.pt2); } - } - bool operator == (const Edge &edge) const - { - return (pt1 == edge.pt1) && (pt2 == edge.pt2); - } + bool operator<(const Edge& edge) const + { + return (pt1 == edge.pt1) ? (pt2 < edge.pt2) : (pt1 < edge.pt1); + } + }; - bool operator < (const Edge &edge) const - { - return (pt1 == edge.pt1) ? (pt2 < edge.pt2) : (pt1 < edge.pt1); - } - }; - - class EdgeInfo - { + class EdgeInfo + { public: - int fcounter[2]; // counter of facets attacted to the edge - MeshGeomFacet facets[2][2]; // Geom-Facets attached to the edge - FacetIndex facet[2]; // underlying Facet-Index + int fcounter[2]; // counter of facets attacted to the edge + MeshGeomFacet facets[2][2]; // Geom-Facets attached to the edge + FacetIndex facet[2]; // underlying Facet-Index - EdgeInfo () - { - fcounter[0] = 0; - fcounter[1] = 0; - facet[0] = 0; - facet[1] = 0; - } - }; + EdgeInfo() + { + fcounter[0] = 0; + fcounter[1] = 0; + facet[0] = 0; + facet[1] = 0; + } + }; - //class CollectFacetVisitor : public MeshFacetVisitor - //{ - // public: - // std::vector &_facets; - // MeshKernel &_mesh; - // std::map &_edges; - // int _side; - // float _mult; - // int _addFacets; // 0: add facets to the result 1: do not add facets to the result - // Base::Builder3D& _builder; + // class CollectFacetVisitor : public MeshFacetVisitor + //{ + // public: + // std::vector &_facets; + // MeshKernel &_mesh; + // std::map &_edges; + // int _side; + // float _mult; + // int _addFacets; // 0: add facets to the result 1: do not add + // facets to the result Base::Builder3D& _builder; - // CollectFacetVisitor (MeshKernel& mesh, std::vector& facets, std::map& edges, int side, float mult, Base::Builder3D& builder); - // bool Visit (MeshFacet &rclFacet, const MeshFacet &rclFrom, unsigned long ulFInd, unsigned long ulLevel); - // bool AllowVisit (MeshFacet& rclFacet, MeshFacet& rclFrom, unsigned long ulFInd, unsigned long ulLevel, unsigned short neighbourIndex); - //}; + // CollectFacetVisitor (MeshKernel& mesh, std::vector& facets, std::map& edges, int side, float mult, Base::Builder3D& builder); bool Visit (MeshFacet + // &rclFacet, const MeshFacet &rclFrom, unsigned long ulFInd, unsigned long ulLevel); bool + // AllowVisit (MeshFacet& rclFacet, MeshFacet& rclFrom, unsigned long ulFInd, unsigned long + // ulLevel, unsigned short neighbourIndex); + //}; - class CollectFacetVisitor : public MeshFacetVisitor - { + class CollectFacetVisitor: public MeshFacetVisitor + { public: - std::vector &_facets; - const MeshKernel &_mesh; - std::map &_edges; - int _side; - float _mult; - int _addFacets{-1}; // 0: add facets to the result 1: do not add facets to the result - Base::Builder3D& _builder; + std::vector& _facets; + const MeshKernel& _mesh; + std::map& _edges; + int _side; + float _mult; + int _addFacets {-1}; // 0: add facets to the result 1: do not add facets to the result + Base::Builder3D& _builder; - CollectFacetVisitor (const MeshKernel& mesh, std::vector& facets, std::map& edges, int side, float mult, Base::Builder3D& builder); - bool Visit (const MeshFacet &rclFacet, const MeshFacet &rclFrom, FacetIndex ulFInd, unsigned long ulLevel) override; - bool AllowVisit (const MeshFacet& rclFacet, const MeshFacet& rclFrom, FacetIndex ulFInd, unsigned long ulLevel, unsigned short neighbourIndex) override; - }; + CollectFacetVisitor(const MeshKernel& mesh, + std::vector& facets, + std::map& edges, + int side, + float mult, + Base::Builder3D& builder); + bool Visit(const MeshFacet& rclFacet, + const MeshFacet& rclFrom, + FacetIndex ulFInd, + unsigned long ulLevel) override; + bool AllowVisit(const MeshFacet& rclFacet, + const MeshFacet& rclFrom, + FacetIndex ulFInd, + unsigned long ulLevel, + unsigned short neighbourIndex) override; + }; - /** all points from cut */ - std::set _cutPoints; - /** all edges */ - std::map _edges; - /** map from facet index to its cut points (mesh 1 and mesh 2) Key: Facet-Index Value: List of iterators of set */ - std::map::iterator> > _facet2points[2]; - /** Facets collected from region growing */ - std::vector _facetsOf[2]; + /** all points from cut */ + std::set _cutPoints; + /** all edges */ + std::map _edges; + /** map from facet index to its cut points (mesh 1 and mesh 2) Key: Facet-Index Value: List of + * iterators of set */ + std::map::iterator>> _facet2points[2]; + /** Facets collected from region growing */ + std::vector _facetsOf[2]; - std::vector _newMeshFacets[2]; + std::vector _newMeshFacets[2]; - /** Cut mesh 1 with mesh 2 */ - void Cut (std::set& facetsNotCuttingEdge0, std::set& facetsCuttingEdge1); - /** Trianglute each facets cut with its cutting points */ - void TriangulateMesh (const MeshKernel &cutMesh, int side); - /** search facets for adding (with region growing) */ - void CollectFacets (int side, float mult); - /** close gap in the mesh */ - void CloseGaps (MeshBuilder& meshBuilder); - - /** visual debugger */ - Base::Builder3D _builder; + /** Cut mesh 1 with mesh 2 */ + void Cut(std::set& facetsNotCuttingEdge0, std::set& facetsCuttingEdge1); + /** Trianglute each facets cut with its cutting points */ + void TriangulateMesh(const MeshKernel& cutMesh, int side); + /** search facets for adding (with region growing) */ + void CollectFacets(int side, float mult); + /** close gap in the mesh */ + void CloseGaps(MeshBuilder& meshBuilder); + /** visual debugger */ + Base::Builder3D _builder; }; /*! @@ -185,35 +208,36 @@ private: class MeshExport MeshIntersection { public: - struct Tuple { + struct Tuple + { Base::Vector3f p1, p2; FacetIndex f1, f2; }; - struct Triple { + struct Triple + { Base::Vector3f p; FacetIndex f1, f2; }; - struct Pair { + struct Pair + { Base::Vector3f p; FacetIndex f; }; - MeshIntersection(const MeshKernel& m1, - const MeshKernel& m2, - float dist) + MeshIntersection(const MeshKernel& m1, const MeshKernel& m2, float dist) : kernel1(m1) , kernel2(m2) , minDistance(dist) - { - } + {} bool hasIntersection() const; void getIntersection(std::list&) const; /*! - From an unsorted list of intersection points make a list of sorted intersection points. If parameter \a onlyclosed - is set to true then only closed intersection curves are taken and all other curves are filtered out. + From an unsorted list of intersection points make a list of sorted intersection points. If + parameter \a onlyclosed is set to true then only closed intersection curves are taken and all + other curves are filtered out. */ - void connectLines(bool onlyclosed, const std::list&, std::list< std::list >&); + void connectLines(bool onlyclosed, const std::list&, std::list>&); private: static bool testIntersection(const MeshKernel& k1, const MeshKernel& k2); @@ -225,6 +249,6 @@ private: }; -} // namespace MeshCore +} // namespace MeshCore #endif // MESH_SETOPERATIONS_H diff --git a/src/Mod/Mesh/App/Core/Simplify.h b/src/Mod/Mesh/App/Core/Simplify.h index 1be04ec744..e2c0cd6672 100644 --- a/src/Mod/Mesh/App/Core/Simplify.h +++ b/src/Mod/Mesh/App/Core/Simplify.h @@ -1,3 +1,4 @@ +// clang-format off // http://voxels.blogspot.de/2014/05/quadric-mesh-simplification-with-source.html // https://github.com/sp4cerat/Fast-Quadric-Mesh-Simplification // @@ -538,3 +539,4 @@ double Simplify::calculate_error(int id_v1, int id_v2, vec3f &p_result) } /////////////////////////////////////////// +// clang-format on diff --git a/src/Mod/Mesh/App/Core/Smoothing.cpp b/src/Mod/Mesh/App/Core/Smoothing.cpp index 3226032c2a..ffeb67d757 100644 --- a/src/Mod/Mesh/App/Core/Smoothing.cpp +++ b/src/Mod/Mesh/App/Core/Smoothing.cpp @@ -24,20 +24,19 @@ #include -#include "Smoothing.h" #include "Algorithm.h" #include "Approximation.h" #include "Iterator.h" #include "MeshKernel.h" +#include "Smoothing.h" using namespace MeshCore; AbstractSmoothing::AbstractSmoothing(MeshKernel& m) - : kernel(m) -{ -} + : kernel(m) +{} AbstractSmoothing::~AbstractSmoothing() = default; @@ -48,9 +47,8 @@ void AbstractSmoothing::initialize(Component comp, Continuity cont) } PlaneFitSmoothing::PlaneFitSmoothing(MeshKernel& m) - : AbstractSmoothing(m) -{ -} + : AbstractSmoothing(m) +{} void PlaneFitSmoothing::Smooth(unsigned int iterations) { @@ -61,24 +59,25 @@ void PlaneFitSmoothing::Smooth(unsigned int iterations) MeshCore::MeshRefPointToPoints vv_it(kernel); MeshCore::MeshPointArray::_TConstIterator v_beg = kernel.GetPoints().begin(); - for (unsigned int i=0; i& cv = vv_it[v_it.Position()]; - if (cv.size() < 3) + if (cv.size() < 3) { continue; + } std::set::const_iterator cv_it; - for (cv_it = cv.begin(); cv_it !=cv.end(); ++cv_it) { + for (cv_it = cv.begin(); cv_it != cv.end(); ++cv_it) { pf.AddPoint(v_beg[*cv_it]); center += v_beg[*cv_it]; } - float scale = 1.0f/(static_cast(cv.size())+1.0f); - center.Scale(scale,scale,scale); + float scale = 1.0f / (static_cast(cv.size()) + 1.0f); + center.Scale(scale, scale, scale); // get the mean plane of the current vertex with the surrounding vertices pf.Fit(); @@ -87,12 +86,13 @@ void PlaneFitSmoothing::Smooth(unsigned int iterations) // look in which direction we should move the vertex L.Set(v_it->x - center.x, v_it->y - center.y, v_it->z - center.z); - if (N*L < 0.0f) + if (N * L < 0.0f) { N.Scale(-1.0, -1.0, -1.0); + } // maximum value to move is distance to mean plane - float d = std::min(fabs(this->maximum),fabs(N*L)); - N.Scale(d,d,d); + float d = std::min(fabs(this->maximum), fabs(N * L)); + N.Scale(d, d, d); PointArray[v_it.Position()].Set(v_it->x - N.x, v_it->y - N.y, v_it->z - N.z); } @@ -105,7 +105,8 @@ void PlaneFitSmoothing::Smooth(unsigned int iterations) } } -void PlaneFitSmoothing::SmoothPoints(unsigned int iterations, const std::vector& point_indices) +void PlaneFitSmoothing::SmoothPoints(unsigned int iterations, + const std::vector& point_indices) { MeshCore::MeshPoint center; MeshCore::MeshPointArray PointArray = kernel.GetPoints(); @@ -114,7 +115,7 @@ void PlaneFitSmoothing::SmoothPoints(unsigned int iterations, const std::vector< MeshCore::MeshRefPointToPoints vv_it(kernel); MeshCore::MeshPointArray::_TConstIterator v_beg = kernel.GetPoints().begin(); - for (unsigned int i=0; i& cv = vv_it[v_it.Position()]; - if (cv.size() < 3) + if (cv.size() < 3) { continue; + } std::set::const_iterator cv_it; - for (cv_it = cv.begin(); cv_it !=cv.end(); ++cv_it) { + for (cv_it = cv.begin(); cv_it != cv.end(); ++cv_it) { pf.AddPoint(v_beg[*cv_it]); center += v_beg[*cv_it]; } - float scale = 1.0f/(static_cast(cv.size())+1.0f); - center.Scale(scale,scale,scale); + float scale = 1.0f / (static_cast(cv.size()) + 1.0f); + center.Scale(scale, scale, scale); // get the mean plane of the current vertex with the surrounding vertices pf.Fit(); @@ -141,12 +143,13 @@ void PlaneFitSmoothing::SmoothPoints(unsigned int iterations, const std::vector< // look in which direction we should move the vertex L.Set(v_it->x - center.x, v_it->y - center.y, v_it->z - center.z); - if (N*L < 0.0f) + if (N * L < 0.0f) { N.Scale(-1.0, -1.0, -1.0); + } // maximum value to move is distance to mean plane - float d = std::min(fabs(this->maximum),fabs(N*L)); - N.Scale(d,d,d); + float d = std::min(fabs(this->maximum), fabs(N * L)); + N.Scale(d, d, d); PointArray[v_it.Position()].Set(v_it->x - N.x, v_it->y - N.y, v_it->z - N.z); } @@ -160,22 +163,22 @@ void PlaneFitSmoothing::SmoothPoints(unsigned int iterations, const std::vector< } LaplaceSmoothing::LaplaceSmoothing(MeshKernel& m) - : AbstractSmoothing(m) -{ -} + : AbstractSmoothing(m) +{} void LaplaceSmoothing::Umbrella(const MeshRefPointToPoints& vv_it, - const MeshRefPointToFacets& vf_it, double stepsize) + const MeshRefPointToFacets& vf_it, + double stepsize) { const MeshCore::MeshPointArray& points = kernel.GetPoints(); - MeshCore::MeshPointArray::_TConstIterator v_it, - v_beg = points.begin(), v_end = points.end(); + MeshCore::MeshPointArray::_TConstIterator v_it, v_beg = points.begin(), v_end = points.end(); PointIndex pos = 0; - for (v_it = points.begin(); v_it != v_end; ++v_it,++pos) { + for (v_it = points.begin(); v_it != v_end; ++v_it, ++pos) { const std::set& cv = vv_it[pos]; - if (cv.size() < 3) + if (cv.size() < 3) { continue; + } if (cv.size() != vf_it[pos].size()) { // do nothing for border points continue; @@ -183,25 +186,26 @@ void LaplaceSmoothing::Umbrella(const MeshRefPointToPoints& vv_it, size_t n_count = cv.size(); double w; - w=1.0/double(n_count); + w = 1.0 / double(n_count); - double delx=0.0,dely=0.0,delz=0.0; + double delx = 0.0, dely = 0.0, delz = 0.0; std::set::const_iterator cv_it; - for (cv_it = cv.begin(); cv_it !=cv.end(); ++cv_it) { - delx += w*static_cast((v_beg[*cv_it]).x-v_it->x); - dely += w*static_cast((v_beg[*cv_it]).y-v_it->y); - delz += w*static_cast((v_beg[*cv_it]).z-v_it->z); + for (cv_it = cv.begin(); cv_it != cv.end(); ++cv_it) { + delx += w * static_cast((v_beg[*cv_it]).x - v_it->x); + dely += w * static_cast((v_beg[*cv_it]).y - v_it->y); + delz += w * static_cast((v_beg[*cv_it]).z - v_it->z); } - float x = static_cast(static_cast(v_it->x)+stepsize*delx); - float y = static_cast(static_cast(v_it->y)+stepsize*dely); - float z = static_cast(static_cast(v_it->z)+stepsize*delz); - kernel.SetPoint(pos,x,y,z); + float x = static_cast(static_cast(v_it->x) + stepsize * delx); + float y = static_cast(static_cast(v_it->y) + stepsize * dely); + float z = static_cast(static_cast(v_it->z) + stepsize * delz); + kernel.SetPoint(pos, x, y, z); } } void LaplaceSmoothing::Umbrella(const MeshRefPointToPoints& vv_it, - const MeshRefPointToFacets& vf_it, double stepsize, + const MeshRefPointToFacets& vf_it, + double stepsize, const std::vector& point_indices) { const MeshCore::MeshPointArray& points = kernel.GetPoints(); @@ -209,8 +213,9 @@ void LaplaceSmoothing::Umbrella(const MeshRefPointToPoints& vv_it, for (PointIndex it : point_indices) { const std::set& cv = vv_it[it]; - if (cv.size() < 3) + if (cv.size() < 3) { continue; + } if (cv.size() != vf_it[it].size()) { // do nothing for border points continue; @@ -218,20 +223,20 @@ void LaplaceSmoothing::Umbrella(const MeshRefPointToPoints& vv_it, size_t n_count = cv.size(); double w; - w=1.0/double(n_count); + w = 1.0 / double(n_count); - double delx=0.0,dely=0.0,delz=0.0; + double delx = 0.0, dely = 0.0, delz = 0.0; std::set::const_iterator cv_it; - for (cv_it = cv.begin(); cv_it !=cv.end(); ++cv_it) { - delx += w*static_cast((v_beg[*cv_it]).x-(v_beg[it]).x); - dely += w*static_cast((v_beg[*cv_it]).y-(v_beg[it]).y); - delz += w*static_cast((v_beg[*cv_it]).z-(v_beg[it]).z); + for (cv_it = cv.begin(); cv_it != cv.end(); ++cv_it) { + delx += w * static_cast((v_beg[*cv_it]).x - (v_beg[it]).x); + dely += w * static_cast((v_beg[*cv_it]).y - (v_beg[it]).y); + delz += w * static_cast((v_beg[*cv_it]).z - (v_beg[it]).z); } - float x = static_cast(static_cast((v_beg[it]).x)+stepsize*delx); - float y = static_cast(static_cast((v_beg[it]).y)+stepsize*dely); - float z = static_cast(static_cast((v_beg[it]).z)+stepsize*delz); - kernel.SetPoint(it,x,y,z); + float x = static_cast(static_cast((v_beg[it]).x) + stepsize * delx); + float y = static_cast(static_cast((v_beg[it]).y) + stepsize * dely); + float z = static_cast(static_cast((v_beg[it]).z) + stepsize * delz); + kernel.SetPoint(it, x, y, z); } } @@ -240,25 +245,25 @@ void LaplaceSmoothing::Smooth(unsigned int iterations) MeshCore::MeshRefPointToPoints vv_it(kernel); MeshCore::MeshRefPointToFacets vf_it(kernel); - for (unsigned int i=0; i& point_indices) +void LaplaceSmoothing::SmoothPoints(unsigned int iterations, + const std::vector& point_indices) { MeshCore::MeshRefPointToPoints vv_it(kernel); MeshCore::MeshRefPointToFacets vf_it(kernel); - for (unsigned int i=0; i& point_indices) +void TaubinSmoothing::SmoothPoints(unsigned int iterations, + const std::vector& point_indices) { MeshCore::MeshRefPointToPoints vv_it(kernel); MeshCore::MeshRefPointToFacets vf_it(kernel); // Theoretically Taubin does not shrink the surface - iterations = (iterations+1)/2; // two steps per iteration - for (unsigned int i=0; i; -inline Base::Vector3d find_median(std::vector &container) +inline Base::Vector3d find_median(std::vector& container) { auto compare_angle_normal = [](const AngleNormal& an1, const AngleNormal& an2) { return an1.first < an2.first; }; size_t n = container.size() / 2; - std::nth_element(container.begin(), container.begin() + n, container.end(), compare_angle_normal); + std::nth_element(container.begin(), + container.begin() + n, + container.end(), + compare_angle_normal); if ((container.size() % 2) == 1) { return container[n].second; } else { // even sized vector -> average the two middle values - auto max_it = std::max_element(container.begin(), container.begin() + n, compare_angle_normal); + auto max_it = + std::max_element(container.begin(), container.begin() + n, compare_angle_normal); Base::Vector3d vec = (max_it->second + container[n].second) / 2.0; vec.Normalize(); return vec; } } -} +} // namespace MedianFilterSmoothing::MedianFilterSmoothing(MeshKernel& m) - : AbstractSmoothing(m) -{ -} + : AbstractSmoothing(m) +{} void MedianFilterSmoothing::Smooth(unsigned int iterations) { @@ -321,17 +331,18 @@ void MedianFilterSmoothing::Smooth(unsigned int iterations) MeshCore::MeshRefFacetToFacets ff_it(kernel); MeshCore::MeshRefPointToFacets vf_it(kernel); - for (unsigned int i=0; i& point_indices) +void MedianFilterSmoothing::SmoothPoints(unsigned int iterations, + const std::vector& point_indices) { MeshCore::MeshRefFacetToFacets ff_it(kernel); MeshCore::MeshRefPointToFacets vf_it(kernel); - for (unsigned int i=0; i&) override; private: - float maximum{FLT_MAX}; + float maximum {FLT_MAX}; }; -class MeshExport LaplaceSmoothing : public AbstractSmoothing +class MeshExport LaplaceSmoothing: public AbstractSmoothing { public: explicit LaplaceSmoothing(MeshKernel&); void Smooth(unsigned int) override; void SmoothPoints(unsigned int, const std::vector&) override; - void SetLambda(double l) { lambda = l;} + void SetLambda(double l) + { + lambda = l; + } protected: + void Umbrella(const MeshRefPointToPoints&, const MeshRefPointToFacets&, double); void Umbrella(const MeshRefPointToPoints&, - const MeshRefPointToFacets&, double); - void Umbrella(const MeshRefPointToPoints&, - const MeshRefPointToFacets&, double, + const MeshRefPointToFacets&, + double, const std::vector&); protected: - double lambda{0.6307}; + double lambda {0.6307}; }; -class MeshExport TaubinSmoothing : public LaplaceSmoothing +class MeshExport TaubinSmoothing: public LaplaceSmoothing { public: explicit TaubinSmoothing(MeshKernel&); void Smooth(unsigned int) override; void SmoothPoints(unsigned int, const std::vector&) override; - void SetMicro(double m) { micro = m;} + void SetMicro(double m) + { + micro = m; + } protected: - double micro{0.0424}; + double micro {0.0424}; }; /*! @@ -117,11 +126,12 @@ protected: * Smoothing based on median filter from the paper: * Mesh Median Filter for Smoothing 3-D Polygonal Surfaces */ -class MeshExport MedianFilterSmoothing : public AbstractSmoothing +class MeshExport MedianFilterSmoothing: public AbstractSmoothing { public: explicit MedianFilterSmoothing(MeshKernel&); - void SetWeight(int w) { + void SetWeight(int w) + { weights = w; } void Smooth(unsigned int) override; @@ -133,10 +143,10 @@ private: const std::vector&); private: - int weights{1}; + int weights {1}; }; -} // namespace MeshCore +} // namespace MeshCore #endif // MESH_SMOOTHING_H diff --git a/src/Mod/Mesh/App/Core/SphereFit.cpp b/src/Mod/Mesh/App/Core/SphereFit.cpp index f87a8c72c9..310f1cca0c 100644 --- a/src/Mod/Mesh/App/Core/SphereFit.cpp +++ b/src/Mod/Mesh/App/Core/SphereFit.cpp @@ -23,9 +23,9 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include +#include +#include +#include #endif #include "SphereFit.h" @@ -34,64 +34,76 @@ using namespace MeshCoreFit; SphereFit::SphereFit() - : _vCenter(0, 0, 0) + : _vCenter(0, 0, 0) {} // Set approximations before calling the fitting -void SphereFit::SetApproximations(double radius, const Base::Vector3d ¢er) +void SphereFit::SetApproximations(double radius, const Base::Vector3d& center) { - _bIsFitted = false; - _fLastResult = FLOAT_MAX; - _numIter = 0; - _dRadius = radius; - _vCenter = center; + _bIsFitted = false; + _fLastResult = FLOAT_MAX; + _numIter = 0; + _dRadius = radius; + _vCenter = center; } // Set iteration convergence criteria for the fit if special values are needed. // The default values set in the constructor are suitable for most uses void SphereFit::SetConvergenceCriteria(double posConvLimit, double vConvLimit, int maxIter) { - if (posConvLimit > 0.0) - _posConvLimit = posConvLimit; - if (vConvLimit > 0.0) - _vConvLimit = vConvLimit; - if (maxIter > 0) - _maxIter = maxIter; + if (posConvLimit > 0.0) { + _posConvLimit = posConvLimit; + } + if (vConvLimit > 0.0) { + _vConvLimit = vConvLimit; + } + if (maxIter > 0) { + _maxIter = maxIter; + } } double SphereFit::GetRadius() const { - if (_bIsFitted) - return _dRadius; - else - return 0.0; + if (_bIsFitted) { + return _dRadius; + } + else { + return 0.0; + } } Base::Vector3d SphereFit::GetCenter() const { - if (_bIsFitted) + if (_bIsFitted) { return _vCenter; - else + } + else { return Base::Vector3d(); + } } int SphereFit::GetNumIterations() const { - if (_bIsFitted) - return _numIter; - else - return 0; + if (_bIsFitted) { + return _numIter; + } + else { + return 0; + } } -float SphereFit::GetDistanceToSphere(const Base::Vector3f &rcPoint) const +float SphereFit::GetDistanceToSphere(const Base::Vector3f& rcPoint) const { - float fResult = FLOAT_MAX; - if (_bIsFitted) - { - fResult = Base::Vector3d((double)rcPoint.x - _vCenter.x, (double)rcPoint.y - _vCenter.y, (double)rcPoint.z - _vCenter.z).Length() - _dRadius; - } - return fResult; + float fResult = FLOAT_MAX; + if (_bIsFitted) { + fResult = Base::Vector3d((double)rcPoint.x - _vCenter.x, + (double)rcPoint.y - _vCenter.y, + (double)rcPoint.z - _vCenter.z) + .Length() + - _dRadius; + } + return fResult; } float SphereFit::GetStdDeviation() const @@ -99,13 +111,14 @@ float SphereFit::GetStdDeviation() const // Mean: M=(1/N)*SUM Xi // Variance: VAR=(N/N-1)*[(1/N)*SUM(Xi^2)-M^2] // Standard deviation: SD=SQRT(VAR) - if (!_bIsFitted) + if (!_bIsFitted) { return FLOAT_MAX; + } double sumXi = 0.0, sumXi2 = 0.0, dist = 0.0; for (auto it : _vPoints) { - dist = GetDistanceToSphere( it ); - sumXi += dist; + dist = GetDistanceToSphere(it); + sumXi += dist; sumXi2 += (dist * dist); } @@ -116,28 +129,28 @@ float SphereFit::GetStdDeviation() const void SphereFit::ProjectToSphere() { - for (auto & cPnt : _vPoints) { - // Compute unit vector from sphere centre to point. - // Because this vector is orthogonal to the sphere's surface at the - // intersection point we can easily compute the projection point on the - // closest surface point using the radius of the sphere - Base::Vector3d diff((double)cPnt.x - _vCenter.x, (double)cPnt.y - _vCenter.y, (double)cPnt.z - _vCenter.z); - double length = diff.Length(); - if (length == 0.0) - { - // Point is exactly at the sphere center, so it can be projected in any direction onto the sphere! - // So here just project in +Z direction - cPnt.z += (float)_dRadius; - } - else - { - diff /= length; // normalizing the vector - Base::Vector3d proj = _vCenter + diff * _dRadius; - cPnt.x = (float)proj.x; - cPnt.y = (float)proj.y; - cPnt.z = (float)proj.z; - } - } + for (auto& cPnt : _vPoints) { + // Compute unit vector from sphere centre to point. + // Because this vector is orthogonal to the sphere's surface at the + // intersection point we can easily compute the projection point on the + // closest surface point using the radius of the sphere + Base::Vector3d diff((double)cPnt.x - _vCenter.x, + (double)cPnt.y - _vCenter.y, + (double)cPnt.z - _vCenter.z); + double length = diff.Length(); + if (length == 0.0) { + // Point is exactly at the sphere center, so it can be projected in any direction onto + // the sphere! So here just project in +Z direction + cPnt.z += (float)_dRadius; + } + else { + diff /= length; // normalizing the vector + Base::Vector3d proj = _vCenter + diff * _dRadius; + cPnt.x = (float)proj.x; + cPnt.y = (float)proj.y; + cPnt.z = (float)proj.z; + } + } } // Compute approximations for the parameters using all points: @@ -145,119 +158,127 @@ void SphereFit::ProjectToSphere() // distance from the centre of gravity to the points. void SphereFit::ComputeApproximations() { - _bIsFitted = false; - _fLastResult = FLOAT_MAX; - _numIter = 0; - _vCenter.Set(0.0, 0.0, 0.0); - _dRadius = 0.0; - if (!_vPoints.empty()) - { - std::list< Base::Vector3f >::const_iterator cIt; - for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) - { - _vCenter.x += cIt->x; - _vCenter.y += cIt->y; - _vCenter.z += cIt->z; - } - _vCenter /= (double)_vPoints.size(); + _bIsFitted = false; + _fLastResult = FLOAT_MAX; + _numIter = 0; + _vCenter.Set(0.0, 0.0, 0.0); + _dRadius = 0.0; + if (!_vPoints.empty()) { + std::list::const_iterator cIt; + for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) { + _vCenter.x += cIt->x; + _vCenter.y += cIt->y; + _vCenter.z += cIt->z; + } + _vCenter /= (double)_vPoints.size(); - for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) - { - Base::Vector3d diff((double)cIt->x - _vCenter.x, (double)cIt->y - _vCenter.y, (double)cIt->z - _vCenter.z); - _dRadius += diff.Length(); - } - _dRadius /= (double)_vPoints.size(); - } + for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) { + Base::Vector3d diff((double)cIt->x - _vCenter.x, + (double)cIt->y - _vCenter.y, + (double)cIt->z - _vCenter.z); + _dRadius += diff.Length(); + } + _dRadius /= (double)_vPoints.size(); + } } float SphereFit::Fit() { - _bIsFitted = false; - _fLastResult = FLOAT_MAX; - _numIter = 0; + _bIsFitted = false; + _fLastResult = FLOAT_MAX; + _numIter = 0; - // A minimum of 4 surface points is needed to define a sphere - if (CountPoints() < 4) - return FLOAT_MAX; + // A minimum of 4 surface points is needed to define a sphere + if (CountPoints() < 4) { + return FLOAT_MAX; + } - // If approximations have not been set/computed then compute some now - if (_dRadius == 0.0) - ComputeApproximations(); + // If approximations have not been set/computed then compute some now + if (_dRadius == 0.0) { + ComputeApproximations(); + } - // Initialise some matrices and vectors - std::vector< Base::Vector3d > residuals(CountPoints(), Base::Vector3d(0.0, 0.0, 0.0)); - Matrix4x4 atpa; - Eigen::VectorXd atpl(4); + // Initialise some matrices and vectors + std::vector residuals(CountPoints(), Base::Vector3d(0.0, 0.0, 0.0)); + Matrix4x4 atpa; + Eigen::VectorXd atpl(4); - // Iteration loop... - double sigma0; - bool cont = true; - while (cont && (_numIter < _maxIter)) - { - ++_numIter; + // Iteration loop... + double sigma0; + bool cont = true; + while (cont && (_numIter < _maxIter)) { + ++_numIter; - // Set up the quasi parametric normal equations - setupNormalEquationMatrices(residuals, atpa, atpl); + // Set up the quasi parametric normal equations + setupNormalEquationMatrices(residuals, atpa, atpl); - // Solve the equations for the unknown corrections - Eigen::LLT< Matrix4x4 > llt(atpa); - if (llt.info() != Eigen::Success) - return FLOAT_MAX; - Eigen::VectorXd x = llt.solve(atpl); + // Solve the equations for the unknown corrections + Eigen::LLT llt(atpa); + if (llt.info() != Eigen::Success) { + return FLOAT_MAX; + } + Eigen::VectorXd x = llt.solve(atpl); - // Check parameter convergence (order of parameters: X,Y,Z,R) - cont = false; - if ((fabs(x(0)) > _posConvLimit) || (fabs(x(1)) > _posConvLimit) || - (fabs(x(2)) > _posConvLimit) || (fabs(x(3)) > _posConvLimit)) - cont = true; + // Check parameter convergence (order of parameters: X,Y,Z,R) + cont = false; + if ((fabs(x(0)) > _posConvLimit) || (fabs(x(1)) > _posConvLimit) + || (fabs(x(2)) > _posConvLimit) || (fabs(x(3)) > _posConvLimit)) { + cont = true; + } - // Before updating the unknowns, compute the residuals and sigma0 and check the residual convergence - bool vConverged; - if (!computeResiduals(x, residuals, sigma0, _vConvLimit, vConverged)) - return FLOAT_MAX; - if (!vConverged) - cont = true; + // Before updating the unknowns, compute the residuals and sigma0 and check the residual + // convergence + bool vConverged; + if (!computeResiduals(x, residuals, sigma0, _vConvLimit, vConverged)) { + return FLOAT_MAX; + } + if (!vConverged) { + cont = true; + } - // Update the parameters (order of parameters: X,Y,Z,R) - _vCenter.x += x(0); - _vCenter.y += x(1); - _vCenter.z += x(2); - _dRadius += x(3); - } + // Update the parameters (order of parameters: X,Y,Z,R) + _vCenter.x += x(0); + _vCenter.y += x(1); + _vCenter.z += x(2); + _dRadius += x(3); + } - // Check for convergence - if (cont) - return FLOAT_MAX; + // Check for convergence + if (cont) { + return FLOAT_MAX; + } - _bIsFitted = true; - _fLastResult = sigma0; + _bIsFitted = true; + _fLastResult = sigma0; - return _fLastResult; + return _fLastResult; } // Set up the normal equation matrices // atpa ... 4x4 normal matrix // atpl ... 4x1 matrix (right-hand side of equation) -void SphereFit::setupNormalEquationMatrices(const std::vector< Base::Vector3d > &residuals, Matrix4x4 &atpa, Eigen::VectorXd &atpl) const +void SphereFit::setupNormalEquationMatrices(const std::vector& residuals, + Matrix4x4& atpa, + Eigen::VectorXd& atpl) const { - // Zero matrices - atpa.setZero(); - atpl.setZero(); + // Zero matrices + atpa.setZero(); + atpl.setZero(); - // For each point, setup the observation equation coefficients and add their - // contribution into the normal equation matrices - double a[4], b[3]; - double f0, qw; - std::vector< Base::Vector3d >::const_iterator vIt = residuals.begin(); - std::list< Base::Vector3f >::const_iterator cIt; - for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt, ++vIt) - { - // if (using this point) { // currently all given points are used (could modify this if eliminating outliers, etc.... - setupObservation(*cIt, *vIt, a, f0, qw, b); - addObservationU(a, f0, qw, atpa, atpl); - // } - } - setLowerPart(atpa); + // For each point, setup the observation equation coefficients and add their + // contribution into the normal equation matrices + double a[4], b[3]; + double f0, qw; + std::vector::const_iterator vIt = residuals.begin(); + std::list::const_iterator cIt; + for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt, ++vIt) { + // if (using this point) { // currently all given points are used (could modify this if + // eliminating outliers, etc.... + setupObservation(*cIt, *vIt, a, f0, qw, b); + addObservationU(a, f0, qw, atpa, atpl); + // } + } + setLowerPart(atpa); } // Sets up contributions of given observation to the quasi parametric @@ -266,40 +287,46 @@ void SphereFit::setupNormalEquationMatrices(const std::vector< Base::Vector3d > // residual ... residual for this point computed from previous iteration (zero for first iteration) // a[4] ... parameter partials (order of parameters: X,Y,Z,R) // f0 ... reference to f0 term -// qw ... reference to quasi weight (here we are assuming equal unit weights for each observed point coordinate) -// b[3] ... observation partials -void SphereFit::setupObservation(const Base::Vector3f &point, const Base::Vector3d &residual, double a[4], double &f0, double &qw, double b[3]) const +// qw ... reference to quasi weight (here we are assuming equal unit weights for each observed +// point coordinate) b[3] ... observation partials +void SphereFit::setupObservation(const Base::Vector3f& point, + const Base::Vector3d& residual, + double a[4], + double& f0, + double& qw, + double b[3]) const { - // This adjustment requires an update of the observation approximations - // because the residuals do not have a linear relationship. - // New estimates for the observations: - double xEstimate = (double)point.x + residual.x; - double yEstimate = (double)point.y + residual.y; - double zEstimate = (double)point.z + residual.z; + // This adjustment requires an update of the observation approximations + // because the residuals do not have a linear relationship. + // New estimates for the observations: + double xEstimate = (double)point.x + residual.x; + double yEstimate = (double)point.y + residual.y; + double zEstimate = (double)point.z + residual.z; - // partials of the observations - double dx = xEstimate - _vCenter.x; - double dy = yEstimate - _vCenter.y; - double dz = zEstimate - _vCenter.z; - b[0] = 2.0 * dx; - b[1] = 2.0 * dy; - b[2] = 2.0 * dz; + // partials of the observations + double dx = xEstimate - _vCenter.x; + double dy = yEstimate - _vCenter.y; + double dz = zEstimate - _vCenter.z; + b[0] = 2.0 * dx; + b[1] = 2.0 * dy; + b[2] = 2.0 * dz; - // partials of the parameters - a[0] = -b[0]; - a[1] = -b[1]; - a[2] = -b[2]; - a[3] = -2.0 * _dRadius; + // partials of the parameters + a[0] = -b[0]; + a[1] = -b[1]; + a[2] = -b[2]; + a[3] = -2.0 * _dRadius; - // free term - f0 = _dRadius * _dRadius - dx * dx - dy * dy - dz * dz + b[0] * residual.x + b[1] * residual.y + b[2] * residual.z; + // free term + f0 = _dRadius * _dRadius - dx * dx - dy * dy - dz * dz + b[0] * residual.x + b[1] * residual.y + + b[2] * residual.z; - // quasi weight (using equal weights for sphere point coordinate observations) - //w[0] = 1.0; - //w[1] = 1.0; - //w[2] = 1.0; - //qw = 1.0 / (b[0] * b[0] / w[0] + b[1] * b[1] / w[1] + b[2] * b[2] / w[2]); - qw = 1.0 / (b[0] * b[0] + b[1] * b[1] + b[2] * b[2]); + // quasi weight (using equal weights for sphere point coordinate observations) + // w[0] = 1.0; + // w[1] = 1.0; + // w[2] = 1.0; + // qw = 1.0 / (b[0] * b[0] / w[0] + b[1] * b[1] / w[1] + b[2] * b[2] / w[2]); + qw = 1.0 / (b[0] * b[0] + b[1] * b[1] + b[2] * b[2]); } // Computes contribution of the given observation equation on the normal equation matrices @@ -312,101 +339,113 @@ void SphereFit::setupObservation(const Base::Vector3f &point, const Base::Vector // pi ... weight of observation (= quasi weight qw for this solution) // atpa ... 4x4 normal equation matrix // atpl ... 4x1 matrix/vector (right-hand side of equations) -void SphereFit::addObservationU(double a[4], double li, double pi, Matrix4x4 &atpa, Eigen::VectorXd &atpl) const +void SphereFit::addObservationU(double a[4], + double li, + double pi, + Matrix4x4& atpa, + Eigen::VectorXd& atpl) const { - for (int i = 0; i < 4; ++i) - { - double aipi = a[i] * pi; - for (int j = i; j < 4; ++j) - { - atpa(i, j) += aipi * a[j]; - //atpa(j, i) = atpa(i, j); // it's a symmetrical matrix, we'll set this later after all observations processed - } - atpl(i) += aipi * li; - } + for (int i = 0; i < 4; ++i) { + double aipi = a[i] * pi; + for (int j = i; j < 4; ++j) { + atpa(i, j) += aipi * a[j]; + // atpa(j, i) = atpa(i, j); // it's a symmetrical matrix, we'll set this later after all + // observations processed + } + atpl(i) += aipi * li; + } } // Set the lower part of the normal matrix equal to the upper part // This is done after all the observations have been added -void SphereFit::setLowerPart(Matrix4x4 &atpa) const +void SphereFit::setLowerPart(Matrix4x4& atpa) const { - for (int i = 0; i < 4; ++i) - { - for (int j = i+1; j < 4; ++j) // skip the diagonal elements - atpa(j, i) = atpa(i, j); - } + for (int i = 0; i < 4; ++i) { + for (int j = i + 1; j < 4; ++j) { // skip the diagonal elements + atpa(j, i) = atpa(i, j); + } + } } // Compute the residuals and sigma0 and check the residual convergence -bool SphereFit::computeResiduals(const Eigen::VectorXd &x, std::vector< Base::Vector3d > &residuals, double &sigma0, double vConvLimit, bool &vConverged) const +bool SphereFit::computeResiduals(const Eigen::VectorXd& x, + std::vector& residuals, + double& sigma0, + double vConvLimit, + bool& vConverged) const { - vConverged = true; - int nPtsUsed = 0; - sigma0 = 0.0; - double a[4], b[3]; - double f0, qw; - //double maxdVx = 0.0; - //double maxdVy = 0.0; - //double maxdVz = 0.0; - //double rmsVv = 0.0; - std::vector< Base::Vector3d >::iterator vIt = residuals.begin(); - std::list< Base::Vector3f >::const_iterator cIt; - for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt, ++vIt) - { - // if (using this point) { // currently all given points are used (could modify this if eliminating outliers, etc.... - ++nPtsUsed; - Base::Vector3d &v = *vIt; - setupObservation(*cIt, v, a, f0, qw, b); - double qv = -f0; - for (int i = 0; i < 4; ++i) - qv += a[i] * x(i); + vConverged = true; + int nPtsUsed = 0; + sigma0 = 0.0; + double a[4], b[3]; + double f0, qw; + // double maxdVx = 0.0; + // double maxdVy = 0.0; + // double maxdVz = 0.0; + // double rmsVv = 0.0; + std::vector::iterator vIt = residuals.begin(); + std::list::const_iterator cIt; + for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt, ++vIt) { + // if (using this point) { // currently all given points are used (could modify this if + // eliminating outliers, etc.... + ++nPtsUsed; + Base::Vector3d& v = *vIt; + setupObservation(*cIt, v, a, f0, qw, b); + double qv = -f0; + for (int i = 0; i < 4; ++i) { + qv += a[i] * x(i); + } - // We are using equal weights for sphere point coordinate observations (see setupObservation) - // i.e. w[0] = w[1] = w[2] = 1.0; - //double vx = -qw * qv * b[0] / w[0]; - //double vy = -qw * qv * b[1] / w[1]; - //double vz = -qw * qv * b[2] / w[2]; - double vx = -qw * qv * b[0]; - double vy = -qw * qv * b[1]; - double vz = -qw * qv * b[2]; - double dVx = fabs(vx - v.x); - double dVy = fabs(vy - v.y); - double dVz = fabs(vz - v.z); - v.x = vx; - v.y = vy; - v.z = vz; + // We are using equal weights for sphere point coordinate observations (see + // setupObservation) i.e. w[0] = w[1] = w[2] = 1.0; + // double vx = -qw * qv * b[0] / w[0]; + // double vy = -qw * qv * b[1] / w[1]; + // double vz = -qw * qv * b[2] / w[2]; + double vx = -qw * qv * b[0]; + double vy = -qw * qv * b[1]; + double vz = -qw * qv * b[2]; + double dVx = fabs(vx - v.x); + double dVy = fabs(vy - v.y); + double dVz = fabs(vz - v.z); + v.x = vx; + v.y = vy; + v.z = vz; - //double vv = v.x * v.x + v.y * v.y + v.z * v.z; - //rmsVv += vv * vv; + // double vv = v.x * v.x + v.y * v.y + v.z * v.z; + // rmsVv += vv * vv; - //sigma0 += v.x * w[0] * v.x + v.y * w[1] * v.y + v.z * w[2] * v.z; - sigma0 += v.x * v.x + v.y * v.y + v.z * v.z; + // sigma0 += v.x * w[0] * v.x + v.y * w[1] * v.y + v.z * w[2] * v.z; + sigma0 += v.x * v.x + v.y * v.y + v.z * v.z; - if ((dVx > vConvLimit) || (dVy > vConvLimit) || (dVz > vConvLimit)) - vConverged = false; + if ((dVx > vConvLimit) || (dVy > vConvLimit) || (dVz > vConvLimit)) { + vConverged = false; + } - //if (dVx > maxdVx) - // maxdVx = dVx; - //if (dVy > maxdVy) - // maxdVy = dVy; - //if (dVz > maxdVz) - // maxdVz = dVz; - } + // if (dVx > maxdVx) + // maxdVx = dVx; + // if (dVy > maxdVy) + // maxdVy = dVy; + // if (dVz > maxdVz) + // maxdVz = dVz; + } - // Compute degrees of freedom and sigma0 - if (nPtsUsed < 4) // A minimum of 4 surface points is needed to define a sphere - { - sigma0 = 0.0; - return false; - } - int df = nPtsUsed - 4; - if (df == 0) - sigma0 = 0.0; - else - sigma0 = sqrt (sigma0 / (double)df); + // Compute degrees of freedom and sigma0 + if (nPtsUsed < 4) // A minimum of 4 surface points is needed to define a sphere + { + sigma0 = 0.0; + return false; + } + int df = nPtsUsed - 4; + if (df == 0) { + sigma0 = 0.0; + } + else { + sigma0 = sqrt(sigma0 / (double)df); + } - //rmsVv = sqrt(rmsVv / (double)nPtsUsed); - //Base::Console().Message("X: %0.3e %0.3e %0.3e %0.3e , Max dV: %0.4f %0.4f %0.4f , RMS Vv: %0.4f\n", x(0), x(1), x(2), x(3), maxdVx, maxdVy, maxdVz, rmsVv); + // rmsVv = sqrt(rmsVv / (double)nPtsUsed); + // Base::Console().Message("X: %0.3e %0.3e %0.3e %0.3e , Max dV: %0.4f %0.4f %0.4f , RMS Vv: + // %0.4f\n", x(0), x(1), x(2), x(3), maxdVx, maxdVy, maxdVz, rmsVv); - return true; + return true; } diff --git a/src/Mod/Mesh/App/Core/SphereFit.h b/src/Mod/Mesh/App/Core/SphereFit.h index 64c2e80a25..f392c66226 100644 --- a/src/Mod/Mesh/App/Core/SphereFit.h +++ b/src/Mod/Mesh/App/Core/SphereFit.h @@ -23,19 +23,20 @@ #ifndef MESH_SPHERE_FIT_H #define MESH_SPHERE_FIT_H -#include #include "Approximation.h" +#include // ------------------------------------------------------------------------------- -namespace MeshCoreFit { +namespace MeshCoreFit +{ -using Matrix4x4 = Eigen::Matrix; +using Matrix4x4 = Eigen::Matrix; /** * Best-fit sphere for a given set of points. */ -class MeshExport SphereFit : public MeshCore::Approximation +class MeshExport SphereFit: public MeshCore::Approximation { public: /** @@ -46,28 +47,30 @@ public: /** * Set approximations before calling Fit() */ - void SetApproximations(double radius, const Base::Vector3d ¢er); + void SetApproximations(double radius, const Base::Vector3d& center); /** - * Set iteration convergence criteria for the fit if special values are needed. - * The default values set in the constructor are suitable for most uses + * Set iteration convergence criteria for the fit if special values are needed. + * The default values set in the constructor are suitable for most uses */ - void SetConvergenceCriteria(double posConvLimit, double vConvLimit, int maxIter); + void SetConvergenceCriteria(double posConvLimit, double vConvLimit, int maxIter); /** * Returns the radius of the fitted sphere. If Fit() has not been called then zero is returned. */ double GetRadius() const; /** - * Returns the center of the fitted sphere. If Fit() has not been called the null vector is returned. + * Returns the center of the fitted sphere. If Fit() has not been called the null vector is + * returned. */ Base::Vector3d GetCenter() const; /** - * Returns the number of iterations that Fit() needed to converge. If Fit() has not been called then zero is returned. + * Returns the number of iterations that Fit() needed to converge. If Fit() has not been called + * then zero is returned. */ - int GetNumIterations() const; + int GetNumIterations() const; /** - * Compute approximations for the parameters using all points + * Compute approximations for the parameters using all points */ - void ComputeApproximations(); + void ComputeApproximations(); /** * Fit a sphere onto the given points. If the fit fails FLOAT_MAX is returned. */ @@ -76,7 +79,7 @@ public: * Returns the distance from the point \a rcPoint to the fitted sphere. If Fit() has not been * called FLOAT_MAX is returned. */ - float GetDistanceToSphere(const Base::Vector3f &rcPoint) const; + float GetDistanceToSphere(const Base::Vector3f& rcPoint) const; /** * Returns the standard deviation from the points to the fitted sphere. If Fit() has not been * called FLOAT_MAX is returned. @@ -88,39 +91,53 @@ public: void ProjectToSphere(); protected: - /** - * Set up the normal equations + /** + * Set up the normal equations */ - void setupNormalEquationMatrices(const std::vector< Base::Vector3d > &residuals, Matrix4x4 &atpa, Eigen::VectorXd &atpl) const; - /** - * Sets up contributions of given observation to the normal equation matrices. + void setupNormalEquationMatrices(const std::vector& residuals, + Matrix4x4& atpa, + Eigen::VectorXd& atpl) const; + /** + * Sets up contributions of given observation to the normal equation matrices. */ - void setupObservation(const Base::Vector3f &point, const Base::Vector3d &residual, double a[4], double &f0, double &qw, double b[3]) const; - /** - * Computes contribution of the given observation equation on the normal equation matrices + void setupObservation(const Base::Vector3f& point, + const Base::Vector3d& residual, + double a[4], + double& f0, + double& qw, + double b[3]) const; + /** + * Computes contribution of the given observation equation on the normal equation matrices */ - void addObservationU(double a[4], double li, double pi, Matrix4x4 &atpa, Eigen::VectorXd &atpl) const; - /** - * Set the lower part of the normal matrix equal to the upper part + void addObservationU(double a[4], + double li, + double pi, + Matrix4x4& atpa, + Eigen::VectorXd& atpl) const; + /** + * Set the lower part of the normal matrix equal to the upper part */ - void setLowerPart(Matrix4x4 &atpa) const; + void setLowerPart(Matrix4x4& atpa) const; - /** - * Compute the residuals and sigma0 and check the residual convergence + /** + * Compute the residuals and sigma0 and check the residual convergence */ - bool computeResiduals(const Eigen::VectorXd &x, std::vector< Base::Vector3d > &residuals, double &sigma0, double vConvLimit, bool &vConverged) const; + bool computeResiduals(const Eigen::VectorXd& x, + std::vector& residuals, + double& sigma0, + double vConvLimit, + bool& vConverged) const; protected: - Base::Vector3d _vCenter;/**< Center of sphere. */ - double _dRadius{0}; /**< Radius of the sphere. */ - int _numIter{0}; /**< Number of iterations for solution to converge. */ - double _posConvLimit{0.0001}; /**< Position and radius parameter convergence threshold. */ - double _vConvLimit{0.001}; /**< Residual convergence threshold. */ - int _maxIter{50}; /**< Maximum number of iterations. */ - + Base::Vector3d _vCenter; /**< Center of sphere. */ + double _dRadius {0}; /**< Radius of the sphere. */ + int _numIter {0}; /**< Number of iterations for solution to converge. */ + double _posConvLimit {0.0001}; /**< Position and radius parameter convergence threshold. */ + double _vConvLimit {0.001}; /**< Residual convergence threshold. */ + int _maxIter {50}; /**< Maximum number of iterations. */ }; -} // namespace MeshCore +} // namespace MeshCoreFit -#endif // MESH_SPHERE_FIT_H +#endif // MESH_SPHERE_FIT_H diff --git a/src/Mod/Mesh/App/Core/Tools.cpp b/src/Mod/Mesh/App/Core/Tools.cpp index b9547649bf..df8cf28d61 100644 --- a/src/Mod/Mesh/App/Core/Tools.cpp +++ b/src/Mod/Mesh/App/Core/Tools.cpp @@ -23,7 +23,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include "Tools.h" @@ -31,33 +31,37 @@ using namespace MeshCore; -MeshSearchNeighbours::MeshSearchNeighbours (const MeshKernel &rclM, float fSampleDistance) - : _rclMesh(rclM) - , _rclFAry(rclM.GetFacets()) - , _rclPAry(rclM.GetPoints()) - , _clPt2Fa(rclM) - , _fSampleDistance(fSampleDistance) +MeshSearchNeighbours::MeshSearchNeighbours(const MeshKernel& rclM, float fSampleDistance) + : _rclMesh(rclM) + , _rclFAry(rclM.GetFacets()) + , _rclPAry(rclM.GetPoints()) + , _clPt2Fa(rclM) + , _fSampleDistance(fSampleDistance) { MeshAlgorithm(_rclMesh).ResetFacetFlag(MeshFacet::MARKED); MeshAlgorithm(_rclMesh).ResetPointFlag(MeshPoint::MARKED); } -void MeshSearchNeighbours::Reinit (float fSampleDistance) +void MeshSearchNeighbours::Reinit(float fSampleDistance) { _fSampleDistance = fSampleDistance; MeshAlgorithm(_rclMesh).ResetFacetFlag(MeshFacet::MARKED); MeshAlgorithm(_rclMesh).ResetPointFlag(MeshPoint::MARKED); } -unsigned long MeshSearchNeighbours::NeighboursFromFacet (FacetIndex ulFacetIdx, float fDistance, unsigned long ulMinPoints, std::vector &raclResultPoints) +unsigned long +MeshSearchNeighbours::NeighboursFromFacet(FacetIndex ulFacetIdx, + float fDistance, + unsigned long ulMinPoints, + std::vector& raclResultPoints) { bool bAddPoints = false; _fMaxDistanceP2 = fDistance * fDistance; - _clCenter = _rclMesh.GetFacet(ulFacetIdx).GetGravityPoint(); + _clCenter = _rclMesh.GetFacet(ulFacetIdx).GetGravityPoint(); unsigned long ulVisited = 1; - std::vector aclTestedFacet; + std::vector aclTestedFacet; _aclResult.clear(); _aclOuter.clear(); @@ -81,16 +85,16 @@ unsigned long MeshSearchNeighbours::NeighboursFromFacet (FacetIndex ulFacetIdx, std::set aclTmp; aclTmp.swap(_aclOuter); for (PointIndex pI : aclTmp) { - const std::set &rclISet = _clPt2Fa[pI]; + const std::set& rclISet = _clPt2Fa[pI]; // search all facets hanging on this point for (FacetIndex pJ : rclISet) { - const MeshFacet &rclF = f_beg[pJ]; + const MeshFacet& rclF = f_beg[pJ]; if (!rclF.IsFlag(MeshFacet::MARKED)) { bool bLF = CheckDistToFacet(rclF); bFound = bFound || bLF; rclF.SetFlag(MeshFacet::MARKED); - aclTestedFacet.push_back(f_beg+pJ); + aclTestedFacet.push_back(f_beg + pJ); } } ulVisited += rclISet.size(); @@ -102,22 +106,27 @@ unsigned long MeshSearchNeighbours::NeighboursFromFacet (FacetIndex ulFacetIdx, bAddPoints = true; bFound = ExpandRadius(ulMinPoints); } - else + else { nCtExpandRadius = 0; + } } // reset marked facets, points - for (auto & pF : aclTestedFacet) + for (auto& pF : aclTestedFacet) { pF->ResetFlag(MeshFacet::MARKED); - for (PointIndex pR : _aclResult) + } + for (PointIndex pR : _aclResult) { _rclPAry[pR].ResetFlag(MeshPoint::MARKED); + } // copy points in result container raclResultPoints.resize(_aclResult.size()); size_t i = 0; - for (std::set::iterator pI = _aclResult.begin(); pI != _aclResult.end(); ++pI, i++) + for (std::set::iterator pI = _aclResult.begin(); pI != _aclResult.end(); + ++pI, i++) { raclResultPoints[i] = _rclPAry[*pI]; + } if (bAddPoints) { // sort points, remove points lying furthest from center @@ -128,10 +137,11 @@ unsigned long MeshSearchNeighbours::NeighboursFromFacet (FacetIndex ulFacetIdx, return ulVisited; } -void MeshSearchNeighbours::SampleAllFacets () +void MeshSearchNeighbours::SampleAllFacets() { - if (_aclSampledFacets.size() == _rclMesh.CountFacets()) - return; // already sampled, do nothing + if (_aclSampledFacets.size() == _rclMesh.CountFacets()) { + return; // already sampled, do nothing + } _aclSampledFacets.resize(_rclMesh.CountFacets()); MeshFacetIterator clFIter(_rclMesh); @@ -144,18 +154,21 @@ void MeshSearchNeighbours::SampleAllFacets () } } -unsigned long MeshSearchNeighbours::NeighboursFromSampledFacets (FacetIndex ulFacetIdx, float fDistance, std::vector &raclResultPoints) +unsigned long +MeshSearchNeighbours::NeighboursFromSampledFacets(FacetIndex ulFacetIdx, + float fDistance, + std::vector& raclResultPoints) { SampleAllFacets(); _fMaxDistanceP2 = fDistance * fDistance; - _clCenter = _rclMesh.GetFacet(ulFacetIdx).GetGravityPoint(); + _clCenter = _rclMesh.GetFacet(ulFacetIdx).GetGravityPoint(); _akSphere.Center = Wm4::Vector3(_clCenter.x, _clCenter.y, _clCenter.z); _akSphere.Radius = fDistance; unsigned long ulVisited = 1; - std::vector aclTestedFacet; + std::vector aclTestedFacet; _aclResult.clear(); _aclOuter.clear(); @@ -173,16 +186,16 @@ unsigned long MeshSearchNeighbours::NeighboursFromSampledFacets (FacetIndex ulFa std::set aclTmp; aclTmp.swap(_aclOuter); for (PointIndex pI : aclTmp) { - const std::set &rclISet = _clPt2Fa[pI]; + const std::set& rclISet = _clPt2Fa[pI]; // search all facets hanging on this point for (FacetIndex pJ : rclISet) { - const MeshFacet &rclF = f_beg[pJ]; + const MeshFacet& rclF = f_beg[pJ]; if (!rclF.IsFlag(MeshFacet::MARKED)) { bool bLF = AccumulateNeighbours(rclF, pJ); bFound = bFound || bLF; rclF.SetFlag(MeshFacet::MARKED); - aclTestedFacet.push_back(f_beg+pJ); + aclTestedFacet.push_back(f_beg + pJ); } } ulVisited += rclISet.size(); @@ -190,8 +203,9 @@ unsigned long MeshSearchNeighbours::NeighboursFromSampledFacets (FacetIndex ulFa } // reset marked facets - for (auto & pF : aclTestedFacet) + for (auto& pF : aclTestedFacet) { pF->ResetFlag(MeshFacet::MARKED); + } // copy points in result container raclResultPoints.resize(_aclPointsResult.size()); @@ -199,40 +213,45 @@ unsigned long MeshSearchNeighbours::NeighboursFromSampledFacets (FacetIndex ulFa // facet points for (PointIndex pI : _aclResult) { - if (InnerPoint(_rclPAry[pI])) + if (InnerPoint(_rclPAry[pI])) { raclResultPoints.push_back(_rclPAry[pI]); + } } return ulVisited; } -bool MeshSearchNeighbours::AccumulateNeighbours (const MeshFacet &rclF, FacetIndex ulFIdx) +bool MeshSearchNeighbours::AccumulateNeighbours(const MeshFacet& rclF, FacetIndex ulFIdx) { - int k = 0; + int k = 0; for (PointIndex ulPIdx : rclF._aulPoints) { _aclOuter.insert(ulPIdx); _aclResult.insert(ulPIdx); - if (Base::DistanceP2(_clCenter, _rclPAry[ulPIdx]) < _fMaxDistanceP2) + if (Base::DistanceP2(_clCenter, _rclPAry[ulPIdx]) < _fMaxDistanceP2) { k++; + } } bool bFound = false; if (k == 3) { // add all sample points - _aclPointsResult.insert(_aclPointsResult.end(), _aclSampledFacets[ulFIdx].begin(), _aclSampledFacets[ulFIdx].end()); + _aclPointsResult.insert(_aclPointsResult.end(), + _aclSampledFacets[ulFIdx].begin(), + _aclSampledFacets[ulFIdx].end()); bFound = true; } else { // add points inner radius bFound = TriangleCutsSphere(rclF); if (bFound) { - const std::vector &rclT = _aclSampledFacets[ulFIdx]; + const std::vector& rclT = _aclSampledFacets[ulFIdx]; std::vector clTmp; clTmp.reserve(rclT.size()); - for (const auto & pI : rclT) { - if (InnerPoint(pI)) + for (const auto& pI : rclT) { + if (InnerPoint(pI)) { clTmp.push_back(pI); + } } _aclPointsResult.insert(_aclPointsResult.end(), clTmp.begin(), clTmp.end()); } @@ -241,30 +260,36 @@ bool MeshSearchNeighbours::AccumulateNeighbours (const MeshFacet &rclF, FacetInd return bFound; } -bool MeshSearchNeighbours::ExpandRadius (unsigned long ulMinPoints) +bool MeshSearchNeighbours::ExpandRadius(unsigned long ulMinPoints) { // add facets from current level _aclResult.insert(_aclOuter.begin(), _aclOuter.end()); - for (PointIndex pI : _aclOuter) + for (PointIndex pI : _aclOuter) { _rclPAry[pI].SetFlag(MeshPoint::MARKED); + } if (_aclResult.size() < ulMinPoints) { _fMaxDistanceP2 *= float(ulMinPoints) / float(_aclResult.size()); return true; } - else + else { return false; + } } -unsigned long MeshSearchNeighbours::NeighboursFacetFromFacet (FacetIndex ulFacetIdx, float fDistance, std::vector &raclResultPoints, std::vector &raclResultFacets) +unsigned long +MeshSearchNeighbours::NeighboursFacetFromFacet(FacetIndex ulFacetIdx, + float fDistance, + std::vector& raclResultPoints, + std::vector& raclResultFacets) { std::set aulFacetSet; _fMaxDistanceP2 = fDistance * fDistance; - _clCenter = _rclMesh.GetFacet(ulFacetIdx).GetGravityPoint(); + _clCenter = _rclMesh.GetFacet(ulFacetIdx).GetGravityPoint(); - unsigned long ulVisited = 1; - std::vector aclTestedFacet; + unsigned long ulVisited = 1; + std::vector aclTestedFacet; _aclResult.clear(); _aclOuter.clear(); @@ -284,10 +309,10 @@ unsigned long MeshSearchNeighbours::NeighboursFacetFromFacet (FacetIndex ulFacet std::set aclTmp; aclTmp.swap(_aclOuter); for (PointIndex pI : aclTmp) { - const std::set &rclISet = _clPt2Fa[pI]; + const std::set& rclISet = _clPt2Fa[pI]; // search all facets hanging on this point for (FacetIndex pJ : rclISet) { - const MeshFacet &rclF = f_beg[pJ]; + const MeshFacet& rclF = f_beg[pJ]; for (PointIndex ptIndex : rclF._aulPoints) { if (Base::DistanceP2(_clCenter, _rclPAry[ptIndex]) < _fMaxDistanceP2) { @@ -301,7 +326,7 @@ unsigned long MeshSearchNeighbours::NeighboursFacetFromFacet (FacetIndex ulFacet bFound = bFound || bLF; rclF.SetFlag(MeshFacet::MARKED); - aclTestedFacet.push_back(f_beg+pJ); + aclTestedFacet.push_back(f_beg + pJ); } } ulVisited += rclISet.size(); @@ -309,16 +334,20 @@ unsigned long MeshSearchNeighbours::NeighboursFacetFromFacet (FacetIndex ulFacet } // reset marked facets, points - for (auto & pF : aclTestedFacet) + for (auto& pF : aclTestedFacet) { pF->ResetFlag(MeshFacet::MARKED); - for (PointIndex pR : _aclResult) + } + for (PointIndex pR : _aclResult) { _rclPAry[pR].ResetFlag(MeshPoint::MARKED); + } // copy points in result container raclResultPoints.resize(_aclResult.size()); size_t i = 0; - for (std::set::iterator pI = _aclResult.begin(); pI != _aclResult.end(); ++pI, i++) + for (std::set::iterator pI = _aclResult.begin(); pI != _aclResult.end(); + ++pI, i++) { raclResultPoints[i] = _rclPAry[*pI]; + } // copy facets in result container raclResultFacets.insert(raclResultFacets.begin(), aulFacetSet.begin(), aulFacetSet.end()); diff --git a/src/Mod/Mesh/App/Core/Tools.h b/src/Mod/Mesh/App/Core/Tools.h index 9920e1d7ee..84eb95bbcc 100644 --- a/src/Mod/Mesh/App/Core/Tools.h +++ b/src/Mod/Mesh/App/Core/Tools.h @@ -33,7 +33,8 @@ #include "MeshKernel.h" -namespace MeshCore { +namespace MeshCore +{ /** * The MeshSearchNeighbours class provides methods to get all points @@ -42,109 +43,122 @@ namespace MeshCore { class MeshSearchNeighbours { public: - explicit MeshSearchNeighbours ( const MeshKernel &rclM, float fSampleDistance = 1.0f); - ~MeshSearchNeighbours () = default; - /** Re-initilaizes internal structures. */ - void Reinit (float fSampleDistance); - /** Collects all neighbour points from the facet (by index), the result are the points of the facets lying - * inside a sphere of radius \a fDistance, center \a center of the original facet. This method uses the - * MARKED flags. - */ - unsigned long NeighboursFromFacet (FacetIndex ulFacetIdx, float fDistance, unsigned long ulMinPoints, std::vector &raclResultPoints); - /** Searches for facets from the start facet, sample the neighbour facets and accumulates the points. */ - unsigned long NeighboursFromSampledFacets (FacetIndex ulFacetIdx, float fDistance, std::vector &raclResultPoints); - /** Searches for facets from the start facet. */ - unsigned long NeighboursFacetFromFacet (FacetIndex ulFacetIdx, float fDistance, std::vector &raclResultPoints, - std::vector &raclResultFacets); + explicit MeshSearchNeighbours(const MeshKernel& rclM, float fSampleDistance = 1.0f); + ~MeshSearchNeighbours() = default; + /** Re-initilaizes internal structures. */ + void Reinit(float fSampleDistance); + /** Collects all neighbour points from the facet (by index), the result are the points of the + * facets lying inside a sphere of radius \a fDistance, center \a center of the original facet. + * This method uses the MARKED flags. + */ + unsigned long NeighboursFromFacet(FacetIndex ulFacetIdx, + float fDistance, + unsigned long ulMinPoints, + std::vector& raclResultPoints); + /** Searches for facets from the start facet, sample the neighbour facets and accumulates the + * points. */ + unsigned long NeighboursFromSampledFacets(FacetIndex ulFacetIdx, + float fDistance, + std::vector& raclResultPoints); + /** Searches for facets from the start facet. */ + unsigned long NeighboursFacetFromFacet(FacetIndex ulFacetIdx, + float fDistance, + std::vector& raclResultPoints, + std::vector& raclResultFacets); protected: - /** Subsamples the mesh. */ - void SampleAllFacets (); - inline bool CheckDistToFacet (const MeshFacet &rclF); // check distance to facet, add points inner radius - bool AccumulateNeighbours (const MeshFacet &rclF, FacetIndex ulFIdx); // accumulate the sample neighbours facet - inline bool InnerPoint (const Base::Vector3f &rclPt) const; - inline bool TriangleCutsSphere (const MeshFacet &rclF) const; - bool ExpandRadius (unsigned long ulMinPoints); + /** Subsamples the mesh. */ + void SampleAllFacets(); + inline bool + CheckDistToFacet(const MeshFacet& rclF); // check distance to facet, add points inner radius + bool AccumulateNeighbours(const MeshFacet& rclF, + FacetIndex ulFIdx); // accumulate the sample neighbours facet + inline bool InnerPoint(const Base::Vector3f& rclPt) const; + inline bool TriangleCutsSphere(const MeshFacet& rclF) const; + bool ExpandRadius(unsigned long ulMinPoints); - struct CDistRad - { - explicit CDistRad (const Base::Vector3f clCenter) : _clCenter(clCenter) {} - bool operator()(const Base::Vector3f &rclPt1, const Base::Vector3f &rclPt2) { return Base::DistanceP2(_clCenter, rclPt1) < Base::DistanceP2(_clCenter, rclPt2); } - Base::Vector3f _clCenter; - }; + struct CDistRad + { + explicit CDistRad(const Base::Vector3f clCenter) + : _clCenter(clCenter) + {} + bool operator()(const Base::Vector3f& rclPt1, const Base::Vector3f& rclPt2) + { + return Base::DistanceP2(_clCenter, rclPt1) < Base::DistanceP2(_clCenter, rclPt2); + } + Base::Vector3f _clCenter; + }; protected: - const MeshKernel &_rclMesh; - const MeshFacetArray &_rclFAry; - const MeshPointArray &_rclPAry; - MeshRefPointToFacets _clPt2Fa; - float _fMaxDistanceP2{0}; // square distance - Base::Vector3f _clCenter; // center points of start facet - std::set _aclResult; // result container (point indices) - std::set _aclOuter; // next searching points - std::vector _aclPointsResult; // result as vertex - std::vector > _aclSampledFacets; // sample points from each facet - float _fSampleDistance; // distance between two sampled points - Wm4::Sphere3 _akSphere; - bool _bTooFewPoints{false}; + const MeshKernel& _rclMesh; + const MeshFacetArray& _rclFAry; + const MeshPointArray& _rclPAry; + MeshRefPointToFacets _clPt2Fa; + float _fMaxDistanceP2 {0}; // square distance + Base::Vector3f _clCenter; // center points of start facet + std::set _aclResult; // result container (point indices) + std::set _aclOuter; // next searching points + std::vector _aclPointsResult; // result as vertex + std::vector> _aclSampledFacets; // sample points from each facet + float _fSampleDistance; // distance between two sampled points + Wm4::Sphere3 _akSphere; + bool _bTooFewPoints {false}; public: - MeshSearchNeighbours (const MeshSearchNeighbours&) = delete; - void operator = (const MeshSearchNeighbours&) = delete; + MeshSearchNeighbours(const MeshSearchNeighbours&) = delete; + void operator=(const MeshSearchNeighbours&) = delete; }; -inline bool MeshSearchNeighbours::CheckDistToFacet (const MeshFacet &rclF) +inline bool MeshSearchNeighbours::CheckDistToFacet(const MeshFacet& rclF) { - bool bFound = false; + bool bFound = false; - for (PointIndex ulPIdx : rclF._aulPoints) - { - if (!_rclPAry[ulPIdx].IsFlag(MeshPoint::MARKED)) - { - if (Base::DistanceP2(_clCenter, _rclPAry[ulPIdx]) < _fMaxDistanceP2) - { - bFound = true; - { - _aclResult.insert(ulPIdx); - _rclPAry[ulPIdx].SetFlag(MeshPoint::MARKED); + for (PointIndex ulPIdx : rclF._aulPoints) { + if (!_rclPAry[ulPIdx].IsFlag(MeshPoint::MARKED)) { + if (Base::DistanceP2(_clCenter, _rclPAry[ulPIdx]) < _fMaxDistanceP2) { + bFound = true; + { + _aclResult.insert(ulPIdx); + _rclPAry[ulPIdx].SetFlag(MeshPoint::MARKED); + } + } + _aclOuter.insert(ulPIdx); } - } - _aclOuter.insert(ulPIdx); } - } - return bFound; + return bFound; } -inline bool MeshSearchNeighbours::InnerPoint (const Base::Vector3f &rclPt) const +inline bool MeshSearchNeighbours::InnerPoint(const Base::Vector3f& rclPt) const { - return Base::DistanceP2(_clCenter, rclPt) < _fMaxDistanceP2; + return Base::DistanceP2(_clCenter, rclPt) < _fMaxDistanceP2; } -inline bool MeshSearchNeighbours::TriangleCutsSphere (const MeshFacet &rclF) const +inline bool MeshSearchNeighbours::TriangleCutsSphere(const MeshFacet& rclF) const { - Base::Vector3f cP0 = _rclPAry[rclF._aulPoints[0]]; - Base::Vector3f cP1 = _rclPAry[rclF._aulPoints[1]]; - Base::Vector3f cP2 = _rclPAry[rclF._aulPoints[2]]; + Base::Vector3f cP0 = _rclPAry[rclF._aulPoints[0]]; + Base::Vector3f cP1 = _rclPAry[rclF._aulPoints[1]]; + Base::Vector3f cP2 = _rclPAry[rclF._aulPoints[2]]; - Wm4::Vector3 akP0(cP0.x, cP0.y, cP0.z); - Wm4::Vector3 akP1(cP1.x, cP1.y, cP1.z); - Wm4::Vector3 akP2(cP2.x, cP2.y, cP2.z); + Wm4::Vector3 akP0(cP0.x, cP0.y, cP0.z); + Wm4::Vector3 akP1(cP1.x, cP1.y, cP1.z); + Wm4::Vector3 akP2(cP2.x, cP2.y, cP2.z); - Wm4::Triangle3 akTri(akP0, akP1, akP2); - Wm4::DistVector3Triangle3 akDistVecTri(_akSphere.Center, akTri); + Wm4::Triangle3 akTri(akP0, akP1, akP2); + Wm4::DistVector3Triangle3 akDistVecTri(_akSphere.Center, akTri); - float fSqrDist = akDistVecTri.GetSquared(); - float fRSqr = _akSphere.Radius*_akSphere.Radius; - return fSqrDist < fRSqr; + float fSqrDist = akDistVecTri.GetSquared(); + float fRSqr = _akSphere.Radius * _akSphere.Radius; + return fSqrDist < fRSqr; } class MeshFaceIterator { public: explicit MeshFaceIterator(const MeshKernel& mesh) - : it(mesh) {} - Base::Vector3f operator() (FacetIndex index) + : it(mesh) + {} + Base::Vector3f operator()(FacetIndex index) { it.Set(index); return it->GetGravityPoint(); @@ -158,8 +172,9 @@ class MeshVertexIterator { public: explicit MeshVertexIterator(const MeshKernel& mesh) - : it(mesh) {} - Base::Vector3f operator() (PointIndex index) + : it(mesh) + {} + Base::Vector3f operator()(PointIndex index) { it.Set(index); return *it; @@ -169,14 +184,20 @@ private: MeshPointIterator it; }; -template +template class MeshNearestIndexToPlane { public: using Index = typename T::Index; - MeshNearestIndexToPlane(const MeshKernel& mesh, const Base::Vector3f& b, const Base::Vector3f& n) - : nearest_index(-1), it(mesh), base(b), normal(n) {} - void operator() (Index index) + MeshNearestIndexToPlane(const MeshKernel& mesh, + const Base::Vector3f& b, + const Base::Vector3f& n) + : nearest_index(-1) + , it(mesh) + , base(b) + , normal(n) + {} + void operator()(Index index) { float dist = (float)fabs(it(index).DistanceToPlane(base, normal)); if (dist < nearest_dist) { @@ -186,15 +207,14 @@ public: } Index nearest_index; - float nearest_dist{FLOAT_MAX}; + float nearest_dist {FLOAT_MAX}; private: T it; Base::Vector3f base, normal; }; -} // namespace MeshCore +} // namespace MeshCore #endif // MESH_TOOLS_H - diff --git a/src/Mod/Mesh/App/Core/TopoAlgorithm.cpp b/src/Mod/Mesh/App/Core/TopoAlgorithm.cpp index e33d338304..f09ad7c596 100644 --- a/src/Mod/Mesh/App/Core/TopoAlgorithm.cpp +++ b/src/Mod/Mesh/App/Core/TopoAlgorithm.cpp @@ -23,143 +23,150 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include -# include +#include +#include +#include +#include #endif #include #include -#include "TopoAlgorithm.h" #include "Evaluation.h" #include "Iterator.h" #include "MeshKernel.h" +#include "TopoAlgorithm.h" #include "Triangulation.h" using namespace MeshCore; -MeshTopoAlgorithm::MeshTopoAlgorithm (MeshKernel &rclM) -: _rclMesh(rclM) +MeshTopoAlgorithm::MeshTopoAlgorithm(MeshKernel& rclM) + : _rclMesh(rclM) +{} + +MeshTopoAlgorithm::~MeshTopoAlgorithm() { + if (_needsCleanup) { + Cleanup(); + } + EndCache(); } -MeshTopoAlgorithm::~MeshTopoAlgorithm () +bool MeshTopoAlgorithm::InsertVertex(FacetIndex ulFacetPos, const Base::Vector3f& rclPoint) { - if ( _needsCleanup ) - Cleanup(); - EndCache(); -} + MeshFacet& rclF = _rclMesh._aclFacetArray[ulFacetPos]; + MeshFacet clNewFacet1, clNewFacet2; -bool MeshTopoAlgorithm::InsertVertex(FacetIndex ulFacetPos, const Base::Vector3f& rclPoint) -{ - MeshFacet& rclF = _rclMesh._aclFacetArray[ulFacetPos]; - MeshFacet clNewFacet1, clNewFacet2; + // insert new point + PointIndex ulPtCnt = _rclMesh._aclPointArray.size(); + PointIndex ulPtInd = this->GetOrAddIndex(rclPoint); + FacetIndex ulSize = _rclMesh._aclFacetArray.size(); - // insert new point - PointIndex ulPtCnt = _rclMesh._aclPointArray.size(); - PointIndex ulPtInd = this->GetOrAddIndex(rclPoint); - FacetIndex ulSize = _rclMesh._aclFacetArray.size(); + if (ulPtInd < ulPtCnt) { + return false; // the given point is already part of the mesh => creating new facets would + // be an illegal operation + } - if ( ulPtInd < ulPtCnt ) - return false; // the given point is already part of the mesh => creating new facets would be an illegal operation + // adjust the facets + // + // first new facet + clNewFacet1._aulPoints[0] = rclF._aulPoints[1]; + clNewFacet1._aulPoints[1] = rclF._aulPoints[2]; + clNewFacet1._aulPoints[2] = ulPtInd; + clNewFacet1._aulNeighbours[0] = rclF._aulNeighbours[1]; + clNewFacet1._aulNeighbours[1] = ulSize + 1; + clNewFacet1._aulNeighbours[2] = ulFacetPos; + // second new facet + clNewFacet2._aulPoints[0] = rclF._aulPoints[2]; + clNewFacet2._aulPoints[1] = rclF._aulPoints[0]; + clNewFacet2._aulPoints[2] = ulPtInd; + clNewFacet2._aulNeighbours[0] = rclF._aulNeighbours[2]; + clNewFacet2._aulNeighbours[1] = ulFacetPos; + clNewFacet2._aulNeighbours[2] = ulSize; + // adjust the neighbour facet + if (rclF._aulNeighbours[1] != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[rclF._aulNeighbours[1]].ReplaceNeighbour(ulFacetPos, ulSize); + } + if (rclF._aulNeighbours[2] != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[rclF._aulNeighbours[2]].ReplaceNeighbour(ulFacetPos, ulSize + 1); + } + // original facet + rclF._aulPoints[2] = ulPtInd; + rclF._aulNeighbours[1] = ulSize; + rclF._aulNeighbours[2] = ulSize + 1; - // adjust the facets - // - // first new facet - clNewFacet1._aulPoints[0] = rclF._aulPoints[1]; - clNewFacet1._aulPoints[1] = rclF._aulPoints[2]; - clNewFacet1._aulPoints[2] = ulPtInd; - clNewFacet1._aulNeighbours[0] = rclF._aulNeighbours[1]; - clNewFacet1._aulNeighbours[1] = ulSize+1; - clNewFacet1._aulNeighbours[2] = ulFacetPos; - // second new facet - clNewFacet2._aulPoints[0] = rclF._aulPoints[2]; - clNewFacet2._aulPoints[1] = rclF._aulPoints[0]; - clNewFacet2._aulPoints[2] = ulPtInd; - clNewFacet2._aulNeighbours[0] = rclF._aulNeighbours[2]; - clNewFacet2._aulNeighbours[1] = ulFacetPos; - clNewFacet2._aulNeighbours[2] = ulSize; - // adjust the neighbour facet - if (rclF._aulNeighbours[1] != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[rclF._aulNeighbours[1]].ReplaceNeighbour(ulFacetPos, ulSize); - if (rclF._aulNeighbours[2] != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[rclF._aulNeighbours[2]].ReplaceNeighbour(ulFacetPos, ulSize+1); - // original facet - rclF._aulPoints[2] = ulPtInd; - rclF._aulNeighbours[1] = ulSize; - rclF._aulNeighbours[2] = ulSize+1; + // insert new facets + _rclMesh._aclFacetArray.push_back(clNewFacet1); + _rclMesh._aclFacetArray.push_back(clNewFacet2); - // insert new facets - _rclMesh._aclFacetArray.push_back(clNewFacet1); - _rclMesh._aclFacetArray.push_back(clNewFacet2); - - return true; + return true; } bool MeshTopoAlgorithm::SnapVertex(FacetIndex ulFacetPos, const Base::Vector3f& rP) { - MeshFacet& rFace = _rclMesh._aclFacetArray[ulFacetPos]; - if (!rFace.HasOpenEdge()) - return false; - Base::Vector3f cNo1 = _rclMesh.GetNormal(rFace); - for (unsigned short i=0; i<3; i++) - { - if (rFace._aulNeighbours[i]==FACET_INDEX_MAX) - { - const Base::Vector3f& rPt1 = _rclMesh._aclPointArray[rFace._aulPoints[i]]; - const Base::Vector3f& rPt2 = _rclMesh._aclPointArray[rFace._aulPoints[(i+1)%3]]; - Base::Vector3f cNo2 = (rPt2 - rPt1) % cNo1; - Base::Vector3f cNo3 = (rP - rPt1) % (rPt2 - rPt1); - float fD2 = Base::DistanceP2(rPt1, rPt2); - float fTV = (rP-rPt1) * (rPt2-rPt1); - - // Point is on the edge - if ( cNo3.Length() < FLOAT_EPS ) - { - return SplitOpenEdge(ulFacetPos, i, rP); - } - else if ( (rP - rPt1)*cNo2 > 0.0f && fD2 >= fTV && fTV >= 0.0f ) - { - MeshFacet cTria; - cTria._aulPoints[0] = this->GetOrAddIndex(rP); - cTria._aulPoints[1] = rFace._aulPoints[(i+1)%3]; - cTria._aulPoints[2] = rFace._aulPoints[i]; - cTria._aulNeighbours[1] = ulFacetPos; - rFace._aulNeighbours[i] = _rclMesh.CountFacets(); - _rclMesh._aclFacetArray.push_back(cTria); - return true; - } + MeshFacet& rFace = _rclMesh._aclFacetArray[ulFacetPos]; + if (!rFace.HasOpenEdge()) { + return false; } - } + Base::Vector3f cNo1 = _rclMesh.GetNormal(rFace); + for (unsigned short i = 0; i < 3; i++) { + if (rFace._aulNeighbours[i] == FACET_INDEX_MAX) { + const Base::Vector3f& rPt1 = _rclMesh._aclPointArray[rFace._aulPoints[i]]; + const Base::Vector3f& rPt2 = _rclMesh._aclPointArray[rFace._aulPoints[(i + 1) % 3]]; + Base::Vector3f cNo2 = (rPt2 - rPt1) % cNo1; + Base::Vector3f cNo3 = (rP - rPt1) % (rPt2 - rPt1); + float fD2 = Base::DistanceP2(rPt1, rPt2); + float fTV = (rP - rPt1) * (rPt2 - rPt1); - return false; + // Point is on the edge + if (cNo3.Length() < FLOAT_EPS) { + return SplitOpenEdge(ulFacetPos, i, rP); + } + else if ((rP - rPt1) * cNo2 > 0.0f && fD2 >= fTV && fTV >= 0.0f) { + MeshFacet cTria; + cTria._aulPoints[0] = this->GetOrAddIndex(rP); + cTria._aulPoints[1] = rFace._aulPoints[(i + 1) % 3]; + cTria._aulPoints[2] = rFace._aulPoints[i]; + cTria._aulNeighbours[1] = ulFacetPos; + rFace._aulNeighbours[i] = _rclMesh.CountFacets(); + _rclMesh._aclFacetArray.push_back(cTria); + return true; + } + } + } + + return false; } void MeshTopoAlgorithm::OptimizeTopology(float fMaxAngle) { // For each internal edge get the adjacent facets. When doing an edge swap we must update // this structure. - std::map, std::vector > aEdge2Face; - for (MeshFacetArray::_TIterator pI = _rclMesh._aclFacetArray.begin(); pI != _rclMesh._aclFacetArray.end(); ++pI) { + std::map, std::vector> aEdge2Face; + for (MeshFacetArray::_TIterator pI = _rclMesh._aclFacetArray.begin(); + pI != _rclMesh._aclFacetArray.end(); + ++pI) { for (int i = 0; i < 3; i++) { // ignore open edges if (pI->_aulNeighbours[i] != FACET_INDEX_MAX) { - PointIndex ulPt0 = std::min(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); - PointIndex ulPt1 = std::max(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); - aEdge2Face[std::pair(ulPt0, ulPt1)].push_back(pI - _rclMesh._aclFacetArray.begin()); + PointIndex ulPt0 = + std::min(pI->_aulPoints[i], pI->_aulPoints[(i + 1) % 3]); + PointIndex ulPt1 = + std::max(pI->_aulPoints[i], pI->_aulPoints[(i + 1) % 3]); + aEdge2Face[std::pair(ulPt0, ulPt1)].push_back( + pI - _rclMesh._aclFacetArray.begin()); } } } // fill up this list with all internal edges and perform swap edges until this list is empty - std::list > aEdgeList; - std::map, std::vector >::iterator pE; + std::list> aEdgeList; + std::map, std::vector>::iterator pE; for (pE = aEdge2Face.begin(); pE != aEdge2Face.end(); ++pE) { - if (pE->second.size() == 2) // make sure that we really have an internal edge + if (pE->second.size() == 2) { // make sure that we really have an internal edge aEdgeList.push_back(pE->first); + } } // to be sure to avoid an endless loop @@ -173,18 +180,20 @@ void MeshTopoAlgorithm::OptimizeTopology(float fMaxAngle) uMaxIter--; // get the adjacent facets to this edge - pE = aEdge2Face.find( aEdge ); + pE = aEdge2Face.find(aEdge); // this edge has been removed some iterations before - if (pE == aEdge2Face.end()) + if (pE == aEdge2Face.end()) { continue; + } // Is swap edge allowed and sensible? - if (!ShouldSwapEdge(pE->second[0], pE->second[1], fMaxAngle)) + if (!ShouldSwapEdge(pE->second[0], pE->second[1], fMaxAngle)) { continue; + } // ok, here we should perform a swap edge to minimize the maximum angle - if ( /*fMax12 > fMax34*/true ) { + if (/*fMax12 > fMax34*/ true) { // swap the edge SwapEdge(pE->second[0], pE->second[1]); @@ -194,36 +203,44 @@ void MeshTopoAlgorithm::OptimizeTopology(float fMaxAngle) unsigned short side2 = rF2.Side(aEdge.first, aEdge.second); // adjust the edge list - for (int i=0; i<3; i++) { - std::map, std::vector >::iterator it; + for (int i = 0; i < 3; i++) { + std::map, std::vector>::iterator it; // first facet - PointIndex ulPt0 = std::min(rF1._aulPoints[i], rF1._aulPoints[(i+1)%3]); - PointIndex ulPt1 = std::max(rF1._aulPoints[i], rF1._aulPoints[(i+1)%3]); - it = aEdge2Face.find( std::make_pair(ulPt0, ulPt1) ); + PointIndex ulPt0 = + std::min(rF1._aulPoints[i], rF1._aulPoints[(i + 1) % 3]); + PointIndex ulPt1 = + std::max(rF1._aulPoints[i], rF1._aulPoints[(i + 1) % 3]); + it = aEdge2Face.find(std::make_pair(ulPt0, ulPt1)); if (it != aEdge2Face.end()) { - if (it->second[0] == pE->second[1]) + if (it->second[0] == pE->second[1]) { it->second[0] = pE->second[0]; - else if (it->second[1] == pE->second[1]) + } + else if (it->second[1] == pE->second[1]) { it->second[1] = pE->second[0]; - aEdgeList.push_back( it->first ); + } + aEdgeList.push_back(it->first); } // second facet - ulPt0 = std::min(rF2._aulPoints[i], rF2._aulPoints[(i+1)%3]); - ulPt1 = std::max(rF2._aulPoints[i], rF2._aulPoints[(i+1)%3]); - it = aEdge2Face.find( std::make_pair(ulPt0, ulPt1) ); + ulPt0 = std::min(rF2._aulPoints[i], rF2._aulPoints[(i + 1) % 3]); + ulPt1 = std::max(rF2._aulPoints[i], rF2._aulPoints[(i + 1) % 3]); + it = aEdge2Face.find(std::make_pair(ulPt0, ulPt1)); if (it != aEdge2Face.end()) { - if (it->second[0] == pE->second[0]) + if (it->second[0] == pE->second[0]) { it->second[0] = pE->second[1]; - else if (it->second[1] == pE->second[0]) + } + else if (it->second[1] == pE->second[0]) { it->second[1] = pE->second[1]; - aEdgeList.push_back( it->first ); + } + aEdgeList.push_back(it->first); } } // Now we must remove the edge and replace it through the new edge - PointIndex ulPt0 = std::min(rF1._aulPoints[(side1+1)%3], rF2._aulPoints[(side2+1)%3]); - PointIndex ulPt1 = std::max(rF1._aulPoints[(side1+1)%3], rF2._aulPoints[(side2+1)%3]); + PointIndex ulPt0 = std::min(rF1._aulPoints[(side1 + 1) % 3], + rF2._aulPoints[(side2 + 1) % 3]); + PointIndex ulPt1 = std::max(rF1._aulPoints[(side1 + 1) % 3], + rF2._aulPoints[(side2 + 1) % 3]); std::pair aNewEdge = std::make_pair(ulPt0, ulPt1); aEdge2Face[aNewEdge] = pE->second; aEdge2Face.erase(pE); @@ -232,29 +249,32 @@ void MeshTopoAlgorithm::OptimizeTopology(float fMaxAngle) } // Cosine of the maximum angle in triangle (v1,v2,v3) -static float cos_maxangle(const Base::Vector3f &v1, - const Base::Vector3f &v2, - const Base::Vector3f &v3) +static float +cos_maxangle(const Base::Vector3f& v1, const Base::Vector3f& v2, const Base::Vector3f& v3) { - float a = Base::Distance(v2,v3); - float b = Base::Distance(v3,v1); - float c = Base::Distance(v1,v2); - float A = a * (b*b + c*c - a*a); - float B = b * (c*c + a*a - b*b); - float C = c * (a*a + b*b - c*c); - return 0.5f * std::min(std::min(A,B),C) / (a*b*c); // min cosine == max angle + float a = Base::Distance(v2, v3); + float b = Base::Distance(v3, v1); + float c = Base::Distance(v1, v2); + float A = a * (b * b + c * c - a * a); + float B = b * (c * c + a * a - b * b); + float C = c * (a * a + b * b - c * c); + return 0.5f * std::min(std::min(A, B), C) + / (a * b * c); // min cosine == max angle } -static float swap_benefit(const Base::Vector3f &v1, const Base::Vector3f &v2, - const Base::Vector3f &v3, const Base::Vector3f &v4) +static float swap_benefit(const Base::Vector3f& v1, + const Base::Vector3f& v2, + const Base::Vector3f& v3, + const Base::Vector3f& v4) { Base::Vector3f n124 = (v4 - v2) % (v1 - v2); Base::Vector3f n234 = (v3 - v2) % (v4 - v2); - if ((n124 * n234) <= 0.0f) - return 0.0f; // avoid normal flip + if ((n124 * n234) <= 0.0f) { + return 0.0f; // avoid normal flip + } - return std::max(-cos_maxangle(v1,v2,v3), -cos_maxangle(v1,v3,v4)) - - std::max(-cos_maxangle(v1,v2,v4), -cos_maxangle(v2,v3,v4)); + return std::max(-cos_maxangle(v1, v2, v3), -cos_maxangle(v1, v3, v4)) + - std::max(-cos_maxangle(v1, v2, v4), -cos_maxangle(v2, v3, v4)); } float MeshTopoAlgorithm::SwapEdgeBenefit(FacetIndex f, int e) const @@ -263,29 +283,29 @@ float MeshTopoAlgorithm::SwapEdgeBenefit(FacetIndex f, int e) const const MeshPointArray& vertices = _rclMesh.GetPoints(); FacetIndex n = faces[f]._aulNeighbours[e]; - if (n == FACET_INDEX_MAX) - return 0.0f; // border edge + if (n == FACET_INDEX_MAX) { + return 0.0f; // border edge + } PointIndex v1 = faces[f]._aulPoints[e]; - PointIndex v2 = faces[f]._aulPoints[(e+1)%3]; - PointIndex v3 = faces[f]._aulPoints[(e+2)%3]; + PointIndex v2 = faces[f]._aulPoints[(e + 1) % 3]; + PointIndex v3 = faces[f]._aulPoints[(e + 2) % 3]; unsigned short s = faces[n].Side(faces[f]); if (s == USHRT_MAX) { std::cerr << "MeshTopoAlgorithm::SwapEdgeBenefit: error in neighbourhood " << "of faces " << f << " and " << n << std::endl; - return 0.0f; // topological error + return 0.0f; // topological error } - PointIndex v4 = faces[n]._aulPoints[(s+2)%3]; + PointIndex v4 = faces[n]._aulPoints[(s + 2) % 3]; if (v3 == v4) { - std::cerr << "MeshTopoAlgorithm::SwapEdgeBenefit: duplicate faces " - << f << " and " << n << std::endl; - return 0.0f; // duplicate faces + std::cerr << "MeshTopoAlgorithm::SwapEdgeBenefit: duplicate faces " << f << " and " << n + << std::endl; + return 0.0f; // duplicate faces } - return swap_benefit(vertices[v2], vertices[v3], - vertices[v1], vertices[v4]); + return swap_benefit(vertices[v2], vertices[v3], vertices[v1], vertices[v4]); } -using FaceEdge = std::pair; // (face, edge) pair +using FaceEdge = std::pair; // (face, edge) pair using FaceEdgePriority = std::pair; void MeshTopoAlgorithm::OptimizeTopology() @@ -298,8 +318,9 @@ void MeshTopoAlgorithm::OptimizeTopology() for (FacetIndex i = 0; i < nf; i++) { for (int j = 0; j < 3; j++) { float b = SwapEdgeBenefit(i, j); - if (b > 0.0f) + if (b > 0.0f) { todo.push(std::make_pair(b, std::make_pair(i, j))); + } } } @@ -309,21 +330,24 @@ void MeshTopoAlgorithm::OptimizeTopology() int e = todo.top().second.second; todo.pop(); // Check again if the swap should still be done - if (SwapEdgeBenefit(f, e) <= 0.0f) + if (SwapEdgeBenefit(f, e) <= 0.0f) { continue; + } // OK, swap the edge FacetIndex f2 = faces[f]._aulNeighbours[e]; SwapEdge(f, f2); // Insert new edges into queue, if necessary for (int j = 0; j < 3; j++) { float b = SwapEdgeBenefit(f, j); - if (b > 0.0f) + if (b > 0.0f) { todo.push(std::make_pair(b, std::make_pair(f, j))); + } } for (int j = 0; j < 3; j++) { float b = SwapEdgeBenefit(f2, j); - if (b > 0.0f) + if (b > 0.0f) { todo.push(std::make_pair(b, std::make_pair(f2, j))); + } } } } @@ -331,9 +355,11 @@ void MeshTopoAlgorithm::OptimizeTopology() void MeshTopoAlgorithm::DelaunayFlip(float fMaxAngle) { // For each internal edge get the adjacent facets. - std::set > aEdge2Face; + std::set> aEdge2Face; FacetIndex index = 0; - for (MeshFacetArray::_TIterator pI = _rclMesh._aclFacetArray.begin(); pI != _rclMesh._aclFacetArray.end(); ++pI, index++) { + for (MeshFacetArray::_TIterator pI = _rclMesh._aclFacetArray.begin(); + pI != _rclMesh._aclFacetArray.end(); + ++pI, index++) { for (FacetIndex nbIndex : pI->_aulNeighbours) { // ignore open edges if (nbIndex != FACET_INDEX_MAX) { @@ -346,7 +372,7 @@ void MeshTopoAlgorithm::DelaunayFlip(float fMaxAngle) Base::Vector3f center; while (!aEdge2Face.empty()) { - std::set >::iterator it = aEdge2Face.begin(); + std::set>::iterator it = aEdge2Face.begin(); std::pair edge = *it; aEdge2Face.erase(it); if (ShouldSwapEdge(edge.first, edge.second, fMaxAngle)) { @@ -355,18 +381,24 @@ void MeshTopoAlgorithm::DelaunayFlip(float fMaxAngle) const MeshFacet& face_1 = _rclMesh._aclFacetArray[edge.first]; const MeshFacet& face_2 = _rclMesh._aclFacetArray[edge.second]; unsigned short side = face_2.Side(edge.first); - Base::Vector3f vertex = _rclMesh.GetPoint(face_2._aulPoints[(side+1)%3]); + Base::Vector3f vertex = _rclMesh.GetPoint(face_2._aulPoints[(side + 1) % 3]); if (Base::DistanceP2(center, vertex) < radius) { SwapEdge(edge.first, edge.second); - for (int i=0; i<3; i++) { - if (face_1._aulNeighbours[i] != FACET_INDEX_MAX && face_1._aulNeighbours[i] != edge.second) { - FacetIndex ulFt0 = std::min(edge.first, face_1._aulNeighbours[i]); - FacetIndex ulFt1 = std::max(edge.first, face_1._aulNeighbours[i]); + for (int i = 0; i < 3; i++) { + if (face_1._aulNeighbours[i] != FACET_INDEX_MAX + && face_1._aulNeighbours[i] != edge.second) { + FacetIndex ulFt0 = + std::min(edge.first, face_1._aulNeighbours[i]); + FacetIndex ulFt1 = + std::max(edge.first, face_1._aulNeighbours[i]); aEdge2Face.insert(std::pair(ulFt0, ulFt1)); } - if (face_2._aulNeighbours[i] != FACET_INDEX_MAX && face_2._aulNeighbours[i] != edge.first) { - FacetIndex ulFt0 = std::min(edge.second, face_2._aulNeighbours[i]); - FacetIndex ulFt1 = std::max(edge.second, face_2._aulNeighbours[i]); + if (face_2._aulNeighbours[i] != FACET_INDEX_MAX + && face_2._aulNeighbours[i] != edge.first) { + FacetIndex ulFt0 = + std::min(edge.second, face_2._aulNeighbours[i]); + FacetIndex ulFt1 = + std::max(edge.second, face_2._aulNeighbours[i]); aEdge2Face.insert(std::pair(ulFt0, ulFt1)); } } @@ -377,29 +409,31 @@ void MeshTopoAlgorithm::DelaunayFlip(float fMaxAngle) int MeshTopoAlgorithm::DelaunayFlip() { - int cnt_swap=0; + int cnt_swap = 0; _rclMesh._aclFacetArray.ResetFlag(MeshFacet::TMP0); size_t cnt_facets = _rclMesh._aclFacetArray.size(); - for (size_t i=0;i > aPnts; - MeshPointIterator cPIt( _rclMesh ); - aPnts.reserve(_rclMesh.CountPoints()); - for ( cPIt.Init(); cPIt.More(); cPIt.Next() ) - aPnts.emplace_back( cPIt->x, cPIt->y, cPIt->z ); - - // get all point connections - std::vector aIdx; - const MeshFacetArray& raFts = _rclMesh.GetFacets(); - aIdx.reserve( 3*raFts.size() ); - - // Build map of edges to the referencing facets - FacetIndex k = 0; - std::map, std::list > aclEdgeMap; - for ( std::vector::const_iterator jt = raFts.begin(); jt != raFts.end(); ++jt, k++ ) - { - for (int i=0; i<3; i++) - { - PointIndex ulT0 = jt->_aulPoints[i]; - PointIndex ulT1 = jt->_aulPoints[(i+1)%3]; - PointIndex ulP0 = std::min(ulT0, ulT1); - PointIndex ulP1 = std::max(ulT0, ulT1); - aclEdgeMap[std::make_pair(ulP0, ulP1)].push_front(k); - aIdx.push_back( static_cast(jt->_aulPoints[i]) ); + std::vector> aPnts; + MeshPointIterator cPIt(_rclMesh); + aPnts.reserve(_rclMesh.CountPoints()); + for (cPIt.Init(); cPIt.More(); cPIt.Next()) { + aPnts.emplace_back(cPIt->x, cPIt->y, cPIt->z); } - } - // compute vertex based curvatures - Wm4::MeshCurvature meshCurv(static_cast(_rclMesh.CountPoints()), &(aPnts[0]), - static_cast(_rclMesh.CountFacets()), &(aIdx[0])); + // get all point connections + std::vector aIdx; + const MeshFacetArray& raFts = _rclMesh.GetFacets(); + aIdx.reserve(3 * raFts.size()); - // get curvature information now - const Wm4::Vector3* aMaxCurvDir = meshCurv.GetMaxDirections(); - const Wm4::Vector3* aMinCurvDir = meshCurv.GetMinDirections(); - const float* aMaxCurv = meshCurv.GetMaxCurvatures(); - const float* aMinCurv = meshCurv.GetMinCurvatures(); - - raFts.ResetFlag(MeshFacet::VISIT); - const MeshPointArray& raPts = _rclMesh.GetPoints(); - for (auto & kt : aclEdgeMap) - { - if ( kt.second.size() == 2 ) { - PointIndex uPt1 = kt.first.first; - PointIndex uPt2 = kt.first.second; - FacetIndex uFt1 = kt.second.front(); - FacetIndex uFt2 = kt.second.back(); - - const MeshFacet& rFace1 = raFts[uFt1]; - const MeshFacet& rFace2 = raFts[uFt2]; - if ( rFace1.IsFlag(MeshFacet::VISIT) || rFace2.IsFlag(MeshFacet::VISIT) ) - continue; - - PointIndex uPt3, uPt4; - unsigned short side = rFace1.Side(uPt1, uPt2); - uPt3 = rFace1._aulPoints[(side+2)%3]; - side = rFace2.Side(uPt1, uPt2); - uPt4 = rFace2._aulPoints[(side+2)%3]; - - Wm4::Vector3 dir; - float fActCurvature; - if ( fabs(aMinCurv[uPt1]) > fabs(aMaxCurv[uPt1]) ) { - fActCurvature = aMinCurv[uPt1]; - dir = aMaxCurvDir[uPt1]; - } else { - fActCurvature = aMaxCurv[uPt1]; - dir = aMinCurvDir[uPt1]; - } - - Base::Vector3f cMinDir(dir.X(), dir.Y(), dir.Z()); - Base::Vector3f cEdgeDir1 = raPts[uPt1] - raPts[uPt2]; - Base::Vector3f cEdgeDir2 = raPts[uPt3] - raPts[uPt4]; - cMinDir.Normalize(); cEdgeDir1.Normalize(); cEdgeDir2.Normalize(); - - // get the plane and calculate the distance to the fourth point - MeshGeomFacet cPlane(raPts[uPt1], raPts[uPt2], raPts[uPt3]); - // positive or negative distance - float fDist = raPts[uPt4].DistanceToPlane(cPlane._aclPoints[0], cPlane.GetNormal()); - - float fLength12 = Base::Distance(raPts[uPt1], raPts[uPt2]); - float fLength34 = Base::Distance(raPts[uPt3], raPts[uPt4]); - if ( fabs(cEdgeDir1*cMinDir) < fabs(cEdgeDir2*cMinDir) ) - { - if ( IsSwapEdgeLegal(uFt1, uFt2) && fLength34 < 1.05f*fLength12 && fActCurvature*fDist > 0.0f) { - SwapEdge(uFt1, uFt2); - rFace1.SetFlag(MeshFacet::VISIT); - rFace2.SetFlag(MeshFacet::VISIT); + // Build map of edges to the referencing facets + FacetIndex k = 0; + std::map, std::list> aclEdgeMap; + for (std::vector::const_iterator jt = raFts.begin(); jt != raFts.end(); ++jt, k++) { + for (int i = 0; i < 3; i++) { + PointIndex ulT0 = jt->_aulPoints[i]; + PointIndex ulT1 = jt->_aulPoints[(i + 1) % 3]; + PointIndex ulP0 = std::min(ulT0, ulT1); + PointIndex ulP1 = std::max(ulT0, ulT1); + aclEdgeMap[std::make_pair(ulP0, ulP1)].push_front(k); + aIdx.push_back(static_cast(jt->_aulPoints[i])); + } + } + + // compute vertex based curvatures + Wm4::MeshCurvature meshCurv(static_cast(_rclMesh.CountPoints()), + &(aPnts[0]), + static_cast(_rclMesh.CountFacets()), + &(aIdx[0])); + + // get curvature information now + const Wm4::Vector3* aMaxCurvDir = meshCurv.GetMaxDirections(); + const Wm4::Vector3* aMinCurvDir = meshCurv.GetMinDirections(); + const float* aMaxCurv = meshCurv.GetMaxCurvatures(); + const float* aMinCurv = meshCurv.GetMinCurvatures(); + + raFts.ResetFlag(MeshFacet::VISIT); + const MeshPointArray& raPts = _rclMesh.GetPoints(); + for (auto& kt : aclEdgeMap) { + if (kt.second.size() == 2) { + PointIndex uPt1 = kt.first.first; + PointIndex uPt2 = kt.first.second; + FacetIndex uFt1 = kt.second.front(); + FacetIndex uFt2 = kt.second.back(); + + const MeshFacet& rFace1 = raFts[uFt1]; + const MeshFacet& rFace2 = raFts[uFt2]; + if (rFace1.IsFlag(MeshFacet::VISIT) || rFace2.IsFlag(MeshFacet::VISIT)) { + continue; + } + + PointIndex uPt3, uPt4; + unsigned short side = rFace1.Side(uPt1, uPt2); + uPt3 = rFace1._aulPoints[(side + 2) % 3]; + side = rFace2.Side(uPt1, uPt2); + uPt4 = rFace2._aulPoints[(side + 2) % 3]; + + Wm4::Vector3 dir; + float fActCurvature; + if (fabs(aMinCurv[uPt1]) > fabs(aMaxCurv[uPt1])) { + fActCurvature = aMinCurv[uPt1]; + dir = aMaxCurvDir[uPt1]; + } + else { + fActCurvature = aMaxCurv[uPt1]; + dir = aMinCurvDir[uPt1]; + } + + Base::Vector3f cMinDir(dir.X(), dir.Y(), dir.Z()); + Base::Vector3f cEdgeDir1 = raPts[uPt1] - raPts[uPt2]; + Base::Vector3f cEdgeDir2 = raPts[uPt3] - raPts[uPt4]; + cMinDir.Normalize(); + cEdgeDir1.Normalize(); + cEdgeDir2.Normalize(); + + // get the plane and calculate the distance to the fourth point + MeshGeomFacet cPlane(raPts[uPt1], raPts[uPt2], raPts[uPt3]); + // positive or negative distance + float fDist = raPts[uPt4].DistanceToPlane(cPlane._aclPoints[0], cPlane.GetNormal()); + + float fLength12 = Base::Distance(raPts[uPt1], raPts[uPt2]); + float fLength34 = Base::Distance(raPts[uPt3], raPts[uPt4]); + if (fabs(cEdgeDir1 * cMinDir) < fabs(cEdgeDir2 * cMinDir)) { + if (IsSwapEdgeLegal(uFt1, uFt2) && fLength34 < 1.05f * fLength12 + && fActCurvature * fDist > 0.0f) { + SwapEdge(uFt1, uFt2); + rFace1.SetFlag(MeshFacet::VISIT); + rFace2.SetFlag(MeshFacet::VISIT); + } + } } - } } - } } -bool MeshTopoAlgorithm::InsertVertexAndSwapEdge(FacetIndex ulFacetPos, const Base::Vector3f& rclPoint, float fMaxAngle) +bool MeshTopoAlgorithm::InsertVertexAndSwapEdge(FacetIndex ulFacetPos, + const Base::Vector3f& rclPoint, + float fMaxAngle) { - if ( !InsertVertex(ulFacetPos, rclPoint) ) - return false; - - // get the created elements - FacetIndex ulF1Ind = _rclMesh._aclFacetArray.size()-2; - FacetIndex ulF2Ind = _rclMesh._aclFacetArray.size()-1; - MeshFacet& rclF1 = _rclMesh._aclFacetArray[ulFacetPos]; - MeshFacet& rclF2 = _rclMesh._aclFacetArray[ulF1Ind]; - MeshFacet& rclF3 = _rclMesh._aclFacetArray[ulF2Ind]; - - // first facet - for (FacetIndex uNeighbour : rclF1._aulNeighbours) - { - if ( uNeighbour!=FACET_INDEX_MAX && uNeighbour!=ulF1Ind && uNeighbour!=ulF2Ind ) - { - if ( ShouldSwapEdge(ulFacetPos, uNeighbour, fMaxAngle) ) { - SwapEdge(ulFacetPos, uNeighbour); - break; - } + if (!InsertVertex(ulFacetPos, rclPoint)) { + return false; } - } - for (FacetIndex uNeighbour : rclF2._aulNeighbours) - { - // second facet - if ( uNeighbour!=FACET_INDEX_MAX && uNeighbour!=ulFacetPos && uNeighbour!=ulF2Ind ) - { - if ( ShouldSwapEdge(ulF1Ind, uNeighbour, fMaxAngle) ) { - SwapEdge(ulF1Ind, uNeighbour); - break; - } - } - } - // third facet - for (FacetIndex uNeighbour : rclF3._aulNeighbours) - { - if ( uNeighbour!=FACET_INDEX_MAX && uNeighbour!=ulFacetPos && uNeighbour!=ulF1Ind ) - { - if ( ShouldSwapEdge(ulF2Ind, uNeighbour, fMaxAngle) ) { - SwapEdge(ulF2Ind, uNeighbour); - break; - } - } - } + // get the created elements + FacetIndex ulF1Ind = _rclMesh._aclFacetArray.size() - 2; + FacetIndex ulF2Ind = _rclMesh._aclFacetArray.size() - 1; + MeshFacet& rclF1 = _rclMesh._aclFacetArray[ulFacetPos]; + MeshFacet& rclF2 = _rclMesh._aclFacetArray[ulF1Ind]; + MeshFacet& rclF3 = _rclMesh._aclFacetArray[ulF2Ind]; - return true; + // first facet + for (FacetIndex uNeighbour : rclF1._aulNeighbours) { + if (uNeighbour != FACET_INDEX_MAX && uNeighbour != ulF1Ind && uNeighbour != ulF2Ind) { + if (ShouldSwapEdge(ulFacetPos, uNeighbour, fMaxAngle)) { + SwapEdge(ulFacetPos, uNeighbour); + break; + } + } + } + for (FacetIndex uNeighbour : rclF2._aulNeighbours) { + // second facet + if (uNeighbour != FACET_INDEX_MAX && uNeighbour != ulFacetPos && uNeighbour != ulF2Ind) { + if (ShouldSwapEdge(ulF1Ind, uNeighbour, fMaxAngle)) { + SwapEdge(ulF1Ind, uNeighbour); + break; + } + } + } + + // third facet + for (FacetIndex uNeighbour : rclF3._aulNeighbours) { + if (uNeighbour != FACET_INDEX_MAX && uNeighbour != ulFacetPos && uNeighbour != ulF1Ind) { + if (ShouldSwapEdge(ulF2Ind, uNeighbour, fMaxAngle)) { + SwapEdge(ulF2Ind, uNeighbour); + break; + } + } + } + + return true; } bool MeshTopoAlgorithm::IsSwapEdgeLegal(FacetIndex ulFacetPos, FacetIndex ulNeighbour) const @@ -567,42 +602,50 @@ bool MeshTopoAlgorithm::IsSwapEdgeLegal(FacetIndex ulFacetPos, FacetIndex ulNeig unsigned short uFSide = rclF.Side(rclN); unsigned short uNSide = rclN.Side(rclF); - if (uFSide == USHRT_MAX || uNSide == USHRT_MAX) - return false; // not neighbours + if (uFSide == USHRT_MAX || uNSide == USHRT_MAX) { + return false; // not neighbours + } Base::Vector3f cP1 = _rclMesh._aclPointArray[rclF._aulPoints[uFSide]]; - Base::Vector3f cP2 = _rclMesh._aclPointArray[rclF._aulPoints[(uFSide+1)%3]]; - Base::Vector3f cP3 = _rclMesh._aclPointArray[rclF._aulPoints[(uFSide+2)%3]]; - Base::Vector3f cP4 = _rclMesh._aclPointArray[rclN._aulPoints[(uNSide+2)%3]]; + Base::Vector3f cP2 = _rclMesh._aclPointArray[rclF._aulPoints[(uFSide + 1) % 3]]; + Base::Vector3f cP3 = _rclMesh._aclPointArray[rclF._aulPoints[(uFSide + 2) % 3]]; + Base::Vector3f cP4 = _rclMesh._aclPointArray[rclN._aulPoints[(uNSide + 2) % 3]]; // do not allow to create degenerated triangles MeshGeomFacet cT3(cP4, cP3, cP1); - if (cT3.IsDegenerated(MeshDefinitions::_fMinPointDistanceP2)) + if (cT3.IsDegenerated(MeshDefinitions::_fMinPointDistanceP2)) { return false; + } MeshGeomFacet cT4(cP3, cP4, cP2); - if (cT4.IsDegenerated(MeshDefinitions::_fMinPointDistanceP2)) + if (cT4.IsDegenerated(MeshDefinitions::_fMinPointDistanceP2)) { return false; + } // We must make sure that the two adjacent triangles builds a convex polygon, otherwise // the swap edge operation is illegal - Base::Vector3f cU = cP2-cP1; - Base::Vector3f cV = cP4-cP3; + Base::Vector3f cU = cP2 - cP1; + Base::Vector3f cV = cP4 - cP3; // build a helper plane through cP1 that must separate cP3 and cP4 Base::Vector3f cN1 = (cU % cV) % cU; - if (((cP3-cP1)*cN1)*((cP4-cP1)*cN1) >= 0.0f) - return false; // not convex + if (((cP3 - cP1) * cN1) * ((cP4 - cP1) * cN1) >= 0.0f) { + return false; // not convex + } // build a helper plane through cP3 that must separate cP1 and cP2 Base::Vector3f cN2 = (cU % cV) % cV; - if (((cP1-cP3)*cN2)*((cP2-cP3)*cN2) >= 0.0f) - return false; // not convex + if (((cP1 - cP3) * cN2) * ((cP2 - cP3) * cN2) >= 0.0f) { + return false; // not convex + } return true; } -bool MeshTopoAlgorithm::ShouldSwapEdge(FacetIndex ulFacetPos, FacetIndex ulNeighbour, float fMaxAngle) const +bool MeshTopoAlgorithm::ShouldSwapEdge(FacetIndex ulFacetPos, + FacetIndex ulNeighbour, + float fMaxAngle) const { - if (!IsSwapEdgeLegal(ulFacetPos, ulNeighbour)) + if (!IsSwapEdgeLegal(ulFacetPos, ulNeighbour)) { return false; + } MeshFacet& rclF = _rclMesh._aclFacetArray[ulFacetPos]; MeshFacet& rclN = _rclMesh._aclFacetArray[ulNeighbour]; @@ -611,25 +654,30 @@ bool MeshTopoAlgorithm::ShouldSwapEdge(FacetIndex ulFacetPos, FacetIndex ulNeigh unsigned short uNSide = rclN.Side(rclF); Base::Vector3f cP1 = _rclMesh._aclPointArray[rclF._aulPoints[uFSide]]; - Base::Vector3f cP2 = _rclMesh._aclPointArray[rclF._aulPoints[(uFSide+1)%3]]; - Base::Vector3f cP3 = _rclMesh._aclPointArray[rclF._aulPoints[(uFSide+2)%3]]; - Base::Vector3f cP4 = _rclMesh._aclPointArray[rclN._aulPoints[(uNSide+2)%3]]; + Base::Vector3f cP2 = _rclMesh._aclPointArray[rclF._aulPoints[(uFSide + 1) % 3]]; + Base::Vector3f cP3 = _rclMesh._aclPointArray[rclF._aulPoints[(uFSide + 2) % 3]]; + Base::Vector3f cP4 = _rclMesh._aclPointArray[rclN._aulPoints[(uNSide + 2) % 3]]; - MeshGeomFacet cT1(cP1, cP2, cP3); float fMax1 = cT1.MaximumAngle(); - MeshGeomFacet cT2(cP2, cP1, cP4); float fMax2 = cT2.MaximumAngle(); - MeshGeomFacet cT3(cP4, cP3, cP1); float fMax3 = cT3.MaximumAngle(); - MeshGeomFacet cT4(cP3, cP4, cP2); float fMax4 = cT4.MaximumAngle(); + MeshGeomFacet cT1(cP1, cP2, cP3); + float fMax1 = cT1.MaximumAngle(); + MeshGeomFacet cT2(cP2, cP1, cP4); + float fMax2 = cT2.MaximumAngle(); + MeshGeomFacet cT3(cP4, cP3, cP1); + float fMax3 = cT3.MaximumAngle(); + MeshGeomFacet cT4(cP3, cP4, cP2); + float fMax4 = cT4.MaximumAngle(); // get the angle between the triangles Base::Vector3f cN1 = cT1.GetNormal(); Base::Vector3f cN2 = cT2.GetNormal(); - if (cN1.GetAngle(cN2) > fMaxAngle) + if (cN1.GetAngle(cN2) > fMaxAngle) { return false; + } float fMax12 = std::max(fMax1, fMax2); float fMax34 = std::max(fMax3, fMax4); - return fMax12 > fMax34; + return fMax12 > fMax34; } void MeshTopoAlgorithm::SwapEdge(FacetIndex ulFacetPos, FacetIndex ulNeighbour) @@ -640,25 +688,33 @@ void MeshTopoAlgorithm::SwapEdge(FacetIndex ulFacetPos, FacetIndex ulNeighbour) unsigned short uFSide = rclF.Side(rclN); unsigned short uNSide = rclN.Side(rclF); - if (uFSide == USHRT_MAX || uNSide == USHRT_MAX) - return; // not neighbours + if (uFSide == USHRT_MAX || uNSide == USHRT_MAX) { + return; // not neighbours + } // adjust the neighbourhood - if (rclF._aulNeighbours[(uFSide+1)%3] != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[rclF._aulNeighbours[(uFSide+1)%3]].ReplaceNeighbour(ulFacetPos, ulNeighbour); - if (rclN._aulNeighbours[(uNSide+1)%3] != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[rclN._aulNeighbours[(uNSide+1)%3]].ReplaceNeighbour(ulNeighbour, ulFacetPos); + if (rclF._aulNeighbours[(uFSide + 1) % 3] != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[rclF._aulNeighbours[(uFSide + 1) % 3]].ReplaceNeighbour( + ulFacetPos, + ulNeighbour); + } + if (rclN._aulNeighbours[(uNSide + 1) % 3] != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[rclN._aulNeighbours[(uNSide + 1) % 3]].ReplaceNeighbour(ulNeighbour, + ulFacetPos); + } // swap the point and neighbour indices - rclF._aulPoints[(uFSide+1)%3] = rclN._aulPoints[(uNSide+2)%3]; - rclN._aulPoints[(uNSide+1)%3] = rclF._aulPoints[(uFSide+2)%3]; - rclF._aulNeighbours[uFSide] = rclN._aulNeighbours[(uNSide+1)%3]; - rclN._aulNeighbours[uNSide] = rclF._aulNeighbours[(uFSide+1)%3]; - rclF._aulNeighbours[(uFSide+1)%3] = ulNeighbour; - rclN._aulNeighbours[(uNSide+1)%3] = ulFacetPos; + rclF._aulPoints[(uFSide + 1) % 3] = rclN._aulPoints[(uNSide + 2) % 3]; + rclN._aulPoints[(uNSide + 1) % 3] = rclF._aulPoints[(uFSide + 2) % 3]; + rclF._aulNeighbours[uFSide] = rclN._aulNeighbours[(uNSide + 1) % 3]; + rclN._aulNeighbours[uNSide] = rclF._aulNeighbours[(uFSide + 1) % 3]; + rclF._aulNeighbours[(uFSide + 1) % 3] = ulNeighbour; + rclN._aulNeighbours[(uNSide + 1) % 3] = ulFacetPos; } -bool MeshTopoAlgorithm::SplitEdge(FacetIndex ulFacetPos, FacetIndex ulNeighbour, const Base::Vector3f& rP) +bool MeshTopoAlgorithm::SplitEdge(FacetIndex ulFacetPos, + FacetIndex ulNeighbour, + const Base::Vector3f& rP) { MeshFacet& rclF = _rclMesh._aclFacetArray[ulFacetPos]; MeshFacet& rclN = _rclMesh._aclFacetArray[ulNeighbour]; @@ -666,8 +722,9 @@ bool MeshTopoAlgorithm::SplitEdge(FacetIndex ulFacetPos, FacetIndex ulNeighbour, unsigned short uFSide = rclF.Side(rclN); unsigned short uNSide = rclN.Side(rclF); - if (uFSide == USHRT_MAX || uNSide == USHRT_MAX) - return false; // not neighbours + if (uFSide == USHRT_MAX || uNSide == USHRT_MAX) { + return false; // not neighbours + } PointIndex uPtCnt = _rclMesh._aclPointArray.size(); PointIndex uPtInd = this->GetOrAddIndex(rP); @@ -675,35 +732,40 @@ bool MeshTopoAlgorithm::SplitEdge(FacetIndex ulFacetPos, FacetIndex ulNeighbour, // the given point is already part of the mesh => creating new facets would // be an illegal operation - if (uPtInd < uPtCnt) + if (uPtInd < uPtCnt) { return false; + } // adjust the neighbourhood - if (rclF._aulNeighbours[(uFSide+1)%3] != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[rclF._aulNeighbours[(uFSide+1)%3]].ReplaceNeighbour(ulFacetPos, ulSize); - if (rclN._aulNeighbours[(uNSide+2)%3] != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[rclN._aulNeighbours[(uNSide+2)%3]].ReplaceNeighbour(ulNeighbour, ulSize+1); + if (rclF._aulNeighbours[(uFSide + 1) % 3] != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[rclF._aulNeighbours[(uFSide + 1) % 3]].ReplaceNeighbour(ulFacetPos, + ulSize); + } + if (rclN._aulNeighbours[(uNSide + 2) % 3] != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[rclN._aulNeighbours[(uNSide + 2) % 3]].ReplaceNeighbour(ulNeighbour, + ulSize + 1); + } MeshFacet cNew1, cNew2; cNew1._aulPoints[0] = uPtInd; - cNew1._aulPoints[1] = rclF._aulPoints[(uFSide+1)%3]; - cNew1._aulPoints[2] = rclF._aulPoints[(uFSide+2)%3]; - cNew1._aulNeighbours[0] = ulSize+1; - cNew1._aulNeighbours[1] = rclF._aulNeighbours[(uFSide+1)%3]; + cNew1._aulPoints[1] = rclF._aulPoints[(uFSide + 1) % 3]; + cNew1._aulPoints[2] = rclF._aulPoints[(uFSide + 2) % 3]; + cNew1._aulNeighbours[0] = ulSize + 1; + cNew1._aulNeighbours[1] = rclF._aulNeighbours[(uFSide + 1) % 3]; cNew1._aulNeighbours[2] = ulFacetPos; cNew2._aulPoints[0] = rclN._aulPoints[uNSide]; cNew2._aulPoints[1] = uPtInd; - cNew2._aulPoints[2] = rclN._aulPoints[(uNSide+2)%3]; + cNew2._aulPoints[2] = rclN._aulPoints[(uNSide + 2) % 3]; cNew2._aulNeighbours[0] = ulSize; cNew2._aulNeighbours[1] = ulNeighbour; - cNew2._aulNeighbours[2] = rclN._aulNeighbours[(uNSide+2)%3]; + cNew2._aulNeighbours[2] = rclN._aulNeighbours[(uNSide + 2) % 3]; // adjust the facets - rclF._aulPoints[(uFSide+1)%3] = uPtInd; - rclF._aulNeighbours[(uFSide+1)%3] = ulSize; + rclF._aulPoints[(uFSide + 1) % 3] = uPtInd; + rclF._aulNeighbours[(uFSide + 1) % 3] = ulSize; rclN._aulPoints[uNSide] = uPtInd; - rclN._aulNeighbours[(uNSide+2)%3] = ulSize+1; + rclN._aulNeighbours[(uNSide + 2) % 3] = ulSize + 1; // insert new facets _rclMesh._aclFacetArray.push_back(cNew1); @@ -712,49 +774,59 @@ bool MeshTopoAlgorithm::SplitEdge(FacetIndex ulFacetPos, FacetIndex ulNeighbour, return true; } -bool MeshTopoAlgorithm::SplitOpenEdge(FacetIndex ulFacetPos, unsigned short uSide, const Base::Vector3f& rP) +bool MeshTopoAlgorithm::SplitOpenEdge(FacetIndex ulFacetPos, + unsigned short uSide, + const Base::Vector3f& rP) { MeshFacet& rclF = _rclMesh._aclFacetArray[ulFacetPos]; - if (rclF._aulNeighbours[uSide] != FACET_INDEX_MAX) - return false; // not open + if (rclF._aulNeighbours[uSide] != FACET_INDEX_MAX) { + return false; // not open + } PointIndex uPtCnt = _rclMesh._aclPointArray.size(); PointIndex uPtInd = this->GetOrAddIndex(rP); FacetIndex ulSize = _rclMesh._aclFacetArray.size(); - if (uPtInd < uPtCnt) - return false; // the given point is already part of the mesh => creating new facets would be an illegal operation + if (uPtInd < uPtCnt) { + return false; // the given point is already part of the mesh => creating new facets would + // be an illegal operation + } // adjust the neighbourhood - if (rclF._aulNeighbours[(uSide+1)%3] != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[rclF._aulNeighbours[(uSide+1)%3]].ReplaceNeighbour(ulFacetPos, ulSize); + if (rclF._aulNeighbours[(uSide + 1) % 3] != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[rclF._aulNeighbours[(uSide + 1) % 3]].ReplaceNeighbour(ulFacetPos, + ulSize); + } MeshFacet cNew; cNew._aulPoints[0] = uPtInd; - cNew._aulPoints[1] = rclF._aulPoints[(uSide+1)%3]; - cNew._aulPoints[2] = rclF._aulPoints[(uSide+2)%3]; + cNew._aulPoints[1] = rclF._aulPoints[(uSide + 1) % 3]; + cNew._aulPoints[2] = rclF._aulPoints[(uSide + 2) % 3]; cNew._aulNeighbours[0] = FACET_INDEX_MAX; - cNew._aulNeighbours[1] = rclF._aulNeighbours[(uSide+1)%3]; + cNew._aulNeighbours[1] = rclF._aulNeighbours[(uSide + 1) % 3]; cNew._aulNeighbours[2] = ulFacetPos; // adjust the facets - rclF._aulPoints[(uSide+1)%3] = uPtInd; - rclF._aulNeighbours[(uSide+1)%3] = ulSize; + rclF._aulPoints[(uSide + 1) % 3] = uPtInd; + rclF._aulNeighbours[(uSide + 1) % 3] = ulSize; // insert new facets _rclMesh._aclFacetArray.push_back(cNew); return true; } -bool MeshTopoAlgorithm::Vertex_Less::operator ()(const Base::Vector3f& u, - const Base::Vector3f& v) const +bool MeshTopoAlgorithm::Vertex_Less::operator()(const Base::Vector3f& u, + const Base::Vector3f& v) const { - if (fabs (u.x - v.x) > FLOAT_EPS) + if (fabs(u.x - v.x) > FLOAT_EPS) { return u.x < v.x; - if (fabs (u.y - v.y) > FLOAT_EPS) + } + if (fabs(u.y - v.y) > FLOAT_EPS) { return u.y < v.y; - if (fabs (u.z - v.z) > FLOAT_EPS) + } + if (fabs(u.z - v.z) > FLOAT_EPS) { return u.z < v.z; + } return false; } @@ -765,8 +837,8 @@ void MeshTopoAlgorithm::BeginCache() } _cache = new tCache(); PointIndex nbPoints = _rclMesh._aclPointArray.size(); - for (unsigned int pntCpt = 0 ; pntCpt < nbPoints ; ++pntCpt) { - _cache->insert(std::make_pair(_rclMesh._aclPointArray[pntCpt],pntCpt)); + for (unsigned int pntCpt = 0; pntCpt < nbPoints; ++pntCpt) { + _cache->insert(std::make_pair(_rclMesh._aclPointArray[pntCpt], pntCpt)); } } @@ -779,19 +851,22 @@ void MeshTopoAlgorithm::EndCache() } } -PointIndex MeshTopoAlgorithm::GetOrAddIndex (const MeshPoint &rclPoint) +PointIndex MeshTopoAlgorithm::GetOrAddIndex(const MeshPoint& rclPoint) { - if (!_cache) + if (!_cache) { return _rclMesh._aclPointArray.GetOrAddIndex(rclPoint); + } unsigned long sz = _rclMesh._aclPointArray.size(); - std::pair retval = _cache->insert(std::make_pair(rclPoint,sz)); - if (retval.second) + std::pair retval = _cache->insert(std::make_pair(rclPoint, sz)); + if (retval.second) { _rclMesh._aclPointArray.push_back(rclPoint); + } return retval.first->second; } -std::vector MeshTopoAlgorithm::GetFacetsToPoint(FacetIndex uFacetPos, PointIndex uPointPos) const +std::vector MeshTopoAlgorithm::GetFacetsToPoint(FacetIndex uFacetPos, + PointIndex uPointPos) const { // get all facets this point is referenced by std::list aReference; @@ -802,22 +877,24 @@ std::vector MeshTopoAlgorithm::GetFacetsToPoint(FacetIndex uFacetPos aReference.pop_front(); aRefFacet.insert(uIndex); MeshFacet& rFace = _rclMesh._aclFacetArray[uIndex]; - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { if (rFace._aulPoints[i] == uPointPos) { if (rFace._aulNeighbours[i] != FACET_INDEX_MAX) { - if (aRefFacet.find(rFace._aulNeighbours[i]) == aRefFacet.end()) - aReference.push_back( rFace._aulNeighbours[i] ); + if (aRefFacet.find(rFace._aulNeighbours[i]) == aRefFacet.end()) { + aReference.push_back(rFace._aulNeighbours[i]); + } } - if (rFace._aulNeighbours[(i+2)%3] != FACET_INDEX_MAX) { - if (aRefFacet.find(rFace._aulNeighbours[(i+2)%3]) == aRefFacet.end()) - aReference.push_back( rFace._aulNeighbours[(i+2)%3] ); + if (rFace._aulNeighbours[(i + 2) % 3] != FACET_INDEX_MAX) { + if (aRefFacet.find(rFace._aulNeighbours[(i + 2) % 3]) == aRefFacet.end()) { + aReference.push_back(rFace._aulNeighbours[(i + 2) % 3]); + } } break; } } } - //copy the items + // copy the items std::vector aRefs; aRefs.insert(aRefs.end(), aRefFacet.begin(), aRefFacet.end()); return aRefs; @@ -831,14 +908,17 @@ void MeshTopoAlgorithm::Cleanup() bool MeshTopoAlgorithm::CollapseVertex(const VertexCollapse& vc) { - if (vc._circumFacets.size() != vc._circumPoints.size()) + if (vc._circumFacets.size() != vc._circumPoints.size()) { return false; + } - if (vc._circumFacets.size() != 3) + if (vc._circumFacets.size() != 3) { return false; + } - if (!_rclMesh._aclPointArray[vc._point].IsValid()) - return false; // the point is marked invalid from a previous run + if (!_rclMesh._aclPointArray[vc._point].IsValid()) { + return false; // the point is marked invalid from a previous run + } MeshFacet& rFace1 = _rclMesh._aclFacetArray[vc._circumFacets[0]]; MeshFacet& rFace2 = _rclMesh._aclFacetArray[vc._circumFacets[1]]; @@ -854,15 +934,16 @@ bool MeshTopoAlgorithm::CollapseVertex(const VertexCollapse& vc) } } - if (ptIndex == POINT_INDEX_MAX) + if (ptIndex == POINT_INDEX_MAX) { return false; + } FacetIndex neighbour1 = FACET_INDEX_MAX; FacetIndex neighbour2 = FACET_INDEX_MAX; const std::vector& faces = vc._circumFacets; // get neighbours that are not part of the faces to be removed - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { if (std::find(faces.begin(), faces.end(), rFace2._aulNeighbours[i]) == faces.end()) { neighbour1 = rFace2._aulNeighbours[i]; } @@ -897,54 +978,67 @@ bool MeshTopoAlgorithm::CollapseVertex(const VertexCollapse& vc) bool MeshTopoAlgorithm::CollapseEdge(FacetIndex ulFacetPos, FacetIndex ulNeighbour) { - MeshFacet& rclF = _rclMesh._aclFacetArray[ulFacetPos]; - MeshFacet& rclN = _rclMesh._aclFacetArray[ulNeighbour]; + MeshFacet& rclF = _rclMesh._aclFacetArray[ulFacetPos]; + MeshFacet& rclN = _rclMesh._aclFacetArray[ulNeighbour]; - unsigned short uFSide = rclF.Side(rclN); - unsigned short uNSide = rclN.Side(rclF); + unsigned short uFSide = rclF.Side(rclN); + unsigned short uNSide = rclN.Side(rclF); - if (uFSide == USHRT_MAX || uNSide == USHRT_MAX) - return false; // not neighbours + if (uFSide == USHRT_MAX || uNSide == USHRT_MAX) { + return false; // not neighbours + } - if (!rclF.IsValid() || !rclN.IsValid()) - return false; // the facets are marked invalid from a previous run + if (!rclF.IsValid() || !rclN.IsValid()) { + return false; // the facets are marked invalid from a previous run + } - // get the point index we want to remove - PointIndex ulPointPos = rclF._aulPoints[uFSide]; - PointIndex ulPointNew = rclN._aulPoints[uNSide]; + // get the point index we want to remove + PointIndex ulPointPos = rclF._aulPoints[uFSide]; + PointIndex ulPointNew = rclN._aulPoints[uNSide]; - // get all facets this point is referenced by - std::vector aRefs = GetFacetsToPoint(ulFacetPos, ulPointPos); - for (FacetIndex it : aRefs) - { - MeshFacet& rFace = _rclMesh._aclFacetArray[it]; - rFace.Transpose( ulPointPos, ulPointNew ); - } + // get all facets this point is referenced by + std::vector aRefs = GetFacetsToPoint(ulFacetPos, ulPointPos); + for (FacetIndex it : aRefs) { + MeshFacet& rFace = _rclMesh._aclFacetArray[it]; + rFace.Transpose(ulPointPos, ulPointNew); + } - // set the new neighbourhood - if (rclF._aulNeighbours[(uFSide+1)%3] != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[rclF._aulNeighbours[(uFSide+1)%3]].ReplaceNeighbour(ulFacetPos, rclF._aulNeighbours[(uFSide+2)%3]); - if (rclF._aulNeighbours[(uFSide+2)%3] != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[rclF._aulNeighbours[(uFSide+2)%3]].ReplaceNeighbour(ulFacetPos, rclF._aulNeighbours[(uFSide+1)%3]); - if (rclN._aulNeighbours[(uNSide+1)%3] != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[rclN._aulNeighbours[(uNSide+1)%3]].ReplaceNeighbour(ulNeighbour, rclN._aulNeighbours[(uNSide+2)%3]); - if (rclN._aulNeighbours[(uNSide+2)%3] != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[rclN._aulNeighbours[(uNSide+2)%3]].ReplaceNeighbour(ulNeighbour, rclN._aulNeighbours[(uNSide+1)%3]); + // set the new neighbourhood + if (rclF._aulNeighbours[(uFSide + 1) % 3] != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[rclF._aulNeighbours[(uFSide + 1) % 3]].ReplaceNeighbour( + ulFacetPos, + rclF._aulNeighbours[(uFSide + 2) % 3]); + } + if (rclF._aulNeighbours[(uFSide + 2) % 3] != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[rclF._aulNeighbours[(uFSide + 2) % 3]].ReplaceNeighbour( + ulFacetPos, + rclF._aulNeighbours[(uFSide + 1) % 3]); + } + if (rclN._aulNeighbours[(uNSide + 1) % 3] != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[rclN._aulNeighbours[(uNSide + 1) % 3]].ReplaceNeighbour( + ulNeighbour, + rclN._aulNeighbours[(uNSide + 2) % 3]); + } + if (rclN._aulNeighbours[(uNSide + 2) % 3] != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[rclN._aulNeighbours[(uNSide + 2) % 3]].ReplaceNeighbour( + ulNeighbour, + rclN._aulNeighbours[(uNSide + 1) % 3]); + } - // isolate the both facets and the point - rclF._aulNeighbours[0] = FACET_INDEX_MAX; - rclF._aulNeighbours[1] = FACET_INDEX_MAX; - rclF._aulNeighbours[2] = FACET_INDEX_MAX; - rclF.SetInvalid(); - rclN._aulNeighbours[0] = FACET_INDEX_MAX; - rclN._aulNeighbours[1] = FACET_INDEX_MAX; - rclN._aulNeighbours[2] = FACET_INDEX_MAX; - rclN.SetInvalid(); - _rclMesh._aclPointArray[ulPointPos].SetInvalid(); + // isolate the both facets and the point + rclF._aulNeighbours[0] = FACET_INDEX_MAX; + rclF._aulNeighbours[1] = FACET_INDEX_MAX; + rclF._aulNeighbours[2] = FACET_INDEX_MAX; + rclF.SetInvalid(); + rclN._aulNeighbours[0] = FACET_INDEX_MAX; + rclN._aulNeighbours[1] = FACET_INDEX_MAX; + rclN._aulNeighbours[2] = FACET_INDEX_MAX; + rclN.SetInvalid(); + _rclMesh._aclPointArray[ulPointPos].SetInvalid(); - _needsCleanup = true; + _needsCleanup = true; - return true; + return true; } bool MeshTopoAlgorithm::IsCollapseEdgeLegal(const EdgeCollapse& ec) const @@ -953,9 +1047,11 @@ bool MeshTopoAlgorithm::IsCollapseEdgeLegal(const EdgeCollapse& ec) const // Check connectivity // std::vector commonPoints; - std::set_intersection(ec._adjacentFrom.begin(), ec._adjacentFrom.end(), - ec._adjacentTo.begin(), ec._adjacentTo.end(), - std::back_insert_iterator >(commonPoints)); + std::set_intersection(ec._adjacentFrom.begin(), + ec._adjacentFrom.end(), + ec._adjacentTo.begin(), + ec._adjacentTo.end(), + std::back_insert_iterator>(commonPoints)); if (commonPoints.size() > 2) { return false; } @@ -964,34 +1060,40 @@ bool MeshTopoAlgorithm::IsCollapseEdgeLegal(const EdgeCollapse& ec) const std::vector::const_iterator it; for (it = ec._changeFacets.begin(); it != ec._changeFacets.end(); ++it) { MeshFacet f = _rclMesh._aclFacetArray[*it]; - if (!f.IsValid()) + if (!f.IsValid()) { return false; + } // ignore the facet(s) at this edge - if (f.HasPoint(ec._fromPoint) && f.HasPoint(ec._toPoint)) + if (f.HasPoint(ec._fromPoint) && f.HasPoint(ec._toPoint)) { continue; + } MeshGeomFacet tria1 = _rclMesh.GetFacet(f); f.Transpose(ec._fromPoint, ec._toPoint); MeshGeomFacet tria2 = _rclMesh.GetFacet(f); - if (tria1.GetNormal() * tria2.GetNormal() < 0.0f) + if (tria1.GetNormal() * tria2.GetNormal() < 0.0f) { return false; + } } // If the data structure is valid and the algorithm works as expected // it should never happen to reject the edge-collapse here! for (it = ec._removeFacets.begin(); it != ec._removeFacets.end(); ++it) { MeshFacet f = _rclMesh._aclFacetArray[*it]; - if (!f.IsValid()) + if (!f.IsValid()) { return false; + } } - if (!_rclMesh._aclPointArray[ec._fromPoint].IsValid()) + if (!_rclMesh._aclPointArray[ec._fromPoint].IsValid()) { return false; + } - if (!_rclMesh._aclPointArray[ec._toPoint].IsValid()) + if (!_rclMesh._aclPointArray[ec._toPoint].IsValid()) { return false; + } return true; } @@ -1008,8 +1110,8 @@ bool MeshTopoAlgorithm::CollapseEdge(const EdgeCollapse& ec) for (FacetIndex nbIndex : f._aulNeighbours) { // get the neighbours of the facet that won't be invalidated if (nbIndex != FACET_INDEX_MAX) { - if (std::find(ec._removeFacets.begin(), ec._removeFacets.end(), - nbIndex) == ec._removeFacets.end()) { + if (std::find(ec._removeFacets.begin(), ec._removeFacets.end(), nbIndex) + == ec._removeFacets.end()) { neighbours.push_back(nbIndex); } } @@ -1041,8 +1143,9 @@ bool MeshTopoAlgorithm::CollapseEdge(const EdgeCollapse& ec) bool MeshTopoAlgorithm::CollapseFacet(FacetIndex ulFacetPos) { MeshFacet& rclF = _rclMesh._aclFacetArray[ulFacetPos]; - if (!rclF.IsValid()) - return false; // the facet is marked invalid from a previous run + if (!rclF.IsValid()) { + return false; // the facet is marked invalid from a previous run + } // get the point index we want to remove PointIndex ulPointInd0 = rclF._aulPoints[0]; @@ -1068,18 +1171,21 @@ bool MeshTopoAlgorithm::CollapseFacet(FacetIndex ulFacetPos) // set the neighbourhood of the circumjacent facets for (FacetIndex nbIndex : rclF._aulNeighbours) { - if (nbIndex == FACET_INDEX_MAX) + if (nbIndex == FACET_INDEX_MAX) { continue; + } MeshFacet& rclN = _rclMesh._aclFacetArray[nbIndex]; unsigned short uNSide = rclN.Side(rclF); - if (rclN._aulNeighbours[(uNSide+1)%3] != FACET_INDEX_MAX) { - _rclMesh._aclFacetArray[rclN._aulNeighbours[(uNSide+1)%3]] - .ReplaceNeighbour(nbIndex,rclN._aulNeighbours[(uNSide+2)%3]); + if (rclN._aulNeighbours[(uNSide + 1) % 3] != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[rclN._aulNeighbours[(uNSide + 1) % 3]].ReplaceNeighbour( + nbIndex, + rclN._aulNeighbours[(uNSide + 2) % 3]); } - if (rclN._aulNeighbours[(uNSide+2)%3] != FACET_INDEX_MAX) { - _rclMesh._aclFacetArray[rclN._aulNeighbours[(uNSide+2)%3]] - .ReplaceNeighbour(nbIndex,rclN._aulNeighbours[(uNSide+1)%3]); + if (rclN._aulNeighbours[(uNSide + 2) % 3] != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[rclN._aulNeighbours[(uNSide + 2) % 3]].ReplaceNeighbour( + nbIndex, + rclN._aulNeighbours[(uNSide + 1) % 3]); } // Isolate the neighbours from the topology @@ -1102,7 +1208,9 @@ bool MeshTopoAlgorithm::CollapseFacet(FacetIndex ulFacetPos) return true; } -void MeshTopoAlgorithm::SplitFacet(FacetIndex ulFacetPos, const Base::Vector3f& rP1, const Base::Vector3f& rP2) +void MeshTopoAlgorithm::SplitFacet(FacetIndex ulFacetPos, + const Base::Vector3f& rP1, + const Base::Vector3f& rP2) { float fEps = MESH_MIN_EDGE_LEN; MeshFacet& rFace = _rclMesh._aclFacetArray[ulFacetPos]; @@ -1112,12 +1220,15 @@ void MeshTopoAlgorithm::SplitFacet(FacetIndex ulFacetPos, const Base::Vector3f& auto pointIndex = [=](const Base::Vector3f& rP) { unsigned short equalP = USHRT_MAX; - if (Base::Distance(rVertex0, rP) < fEps) + if (Base::Distance(rVertex0, rP) < fEps) { equalP = 0; - else if (Base::Distance(rVertex1, rP) < fEps) + } + else if (Base::Distance(rVertex1, rP) < fEps) { equalP = 1; - else if (Base::Distance(rVertex2, rP) < fEps) + } + else if (Base::Distance(rVertex2, rP) < fEps) { equalP = 2; + } return equalP; }; @@ -1125,8 +1236,9 @@ void MeshTopoAlgorithm::SplitFacet(FacetIndex ulFacetPos, const Base::Vector3f& unsigned short equalP2 = pointIndex(rP2); // both points are coincident with the corner points - if (equalP1 != USHRT_MAX && equalP2 != USHRT_MAX) - return; // must not split the facet + if (equalP1 != USHRT_MAX && equalP2 != USHRT_MAX) { + return; // must not split the facet + } if (equalP1 != USHRT_MAX) { // get the edge to the second given point and perform a split edge operation @@ -1147,9 +1259,9 @@ void MeshTopoAlgorithm::SplitFacetOnOneEdge(FacetIndex ulFacetPos, const Base::V unsigned short iEdgeNo = USHRT_MAX; MeshFacet& rFace = _rclMesh._aclFacetArray[ulFacetPos]; - for (unsigned short i=0; i<3; i++) { + for (unsigned short i = 0; i < 3; i++) { Base::Vector3f cBase(_rclMesh._aclPointArray[rFace._aulPoints[i]]); - Base::Vector3f cEnd (_rclMesh._aclPointArray[rFace._aulPoints[(i+1)%3]]); + Base::Vector3f cEnd(_rclMesh._aclPointArray[rFace._aulPoints[(i + 1) % 3]]); Base::Vector3f cDir = cEnd - cBase; float fDist = rP.DistanceToLine(cBase, cDir); @@ -1160,23 +1272,27 @@ void MeshTopoAlgorithm::SplitFacetOnOneEdge(FacetIndex ulFacetPos, const Base::V } if (fMinDist < 0.05f) { - if (rFace._aulNeighbours[iEdgeNo] != FACET_INDEX_MAX) + if (rFace._aulNeighbours[iEdgeNo] != FACET_INDEX_MAX) { SplitEdge(ulFacetPos, rFace._aulNeighbours[iEdgeNo], rP); - else + } + else { SplitOpenEdge(ulFacetPos, iEdgeNo, rP); + } } } -void MeshTopoAlgorithm::SplitFacetOnTwoEdges(FacetIndex ulFacetPos, const Base::Vector3f& rP1, const Base::Vector3f& rP2) +void MeshTopoAlgorithm::SplitFacetOnTwoEdges(FacetIndex ulFacetPos, + const Base::Vector3f& rP1, + const Base::Vector3f& rP2) { // search for the matching edges unsigned short iEdgeNo1 = USHRT_MAX, iEdgeNo2 = USHRT_MAX; float fMinDist1 = FLOAT_MAX, fMinDist2 = FLOAT_MAX; MeshFacet& rFace = _rclMesh._aclFacetArray[ulFacetPos]; - for (unsigned short i=0; i<3; i++) { + for (unsigned short i = 0; i < 3; i++) { Base::Vector3f cBase(_rclMesh._aclPointArray[rFace._aulPoints[i]]); - Base::Vector3f cEnd (_rclMesh._aclPointArray[rFace._aulPoints[(i+1)%3]]); + Base::Vector3f cEnd(_rclMesh._aclPointArray[rFace._aulPoints[(i + 1) % 3]]); Base::Vector3f cDir = cEnd - cBase; float fDist = rP1.DistanceToLine(cBase, cDir); @@ -1191,8 +1307,9 @@ void MeshTopoAlgorithm::SplitFacetOnTwoEdges(FacetIndex ulFacetPos, const Base:: } } - if (iEdgeNo1 == iEdgeNo2 || fMinDist1 >= 0.05f || fMinDist2 >= 0.05f) - return; // no valid configuration + if (iEdgeNo1 == iEdgeNo2 || fMinDist1 >= 0.05f || fMinDist2 >= 0.05f) { + return; // no valid configuration + } // make first point lying on the previous edge Base::Vector3f cP1 = rP1; @@ -1248,21 +1365,23 @@ void MeshTopoAlgorithm::SplitFacetOnTwoEdges(FacetIndex ulFacetPos, const Base:: if (n1 != FACET_INDEX_MAX) { fixIndices.push_back(n1); MeshFacet& rN = _rclMesh._aclFacetArray[n1]; - for (FacetIndex nbIndex : rN._aulNeighbours) + for (FacetIndex nbIndex : rN._aulNeighbours) { fixIndices.push_back(nbIndex); + } SplitFacet(n1, p1, p2, cntPts1); } if (n2 != FACET_INDEX_MAX) { fixIndices.push_back(n2); MeshFacet& rN = _rclMesh._aclFacetArray[n2]; - for (FacetIndex nbIndex : rN._aulNeighbours) + for (FacetIndex nbIndex : rN._aulNeighbours) { fixIndices.push_back(nbIndex); + } SplitFacet(n2, p2, p0, cntPts2); } FacetIndex cntFts2 = _rclMesh.CountFacets(); - for (FacetIndex i=cntFts; i& ulFac void MeshTopoAlgorithm::HarmonizeNeighbours(FacetIndex facet1, FacetIndex facet2) { - if (facet1 == facet2) + if (facet1 == facet2) { return; + } MeshFacet& rFace1 = _rclMesh._aclFacetArray[facet1]; MeshFacet& rFace2 = _rclMesh._aclFacetArray[facet2]; @@ -1343,36 +1470,40 @@ void MeshTopoAlgorithm::HarmonizeNeighbours(FacetIndex facet1, FacetIndex facet2 } } -void MeshTopoAlgorithm::SplitNeighbourFacet(FacetIndex ulFacetPos, unsigned short uFSide, const Base::Vector3f rPoint) +void MeshTopoAlgorithm::SplitNeighbourFacet(FacetIndex ulFacetPos, + unsigned short uFSide, + const Base::Vector3f rPoint) { - MeshFacet& rclF = _rclMesh._aclFacetArray[ulFacetPos]; + MeshFacet& rclF = _rclMesh._aclFacetArray[ulFacetPos]; - FacetIndex ulNeighbour = rclF._aulNeighbours[uFSide]; - MeshFacet& rclN = _rclMesh._aclFacetArray[ulNeighbour]; + FacetIndex ulNeighbour = rclF._aulNeighbours[uFSide]; + MeshFacet& rclN = _rclMesh._aclFacetArray[ulNeighbour]; - unsigned short uNSide = rclN.Side(rclF); + unsigned short uNSide = rclN.Side(rclF); - PointIndex uPtInd = this->GetOrAddIndex(rPoint); - FacetIndex ulSize = _rclMesh._aclFacetArray.size(); + PointIndex uPtInd = this->GetOrAddIndex(rPoint); + FacetIndex ulSize = _rclMesh._aclFacetArray.size(); - // adjust the neighbourhood - if (rclN._aulNeighbours[(uNSide+1)%3] != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[rclN._aulNeighbours[(uNSide+1)%3]].ReplaceNeighbour(ulNeighbour, ulSize); + // adjust the neighbourhood + if (rclN._aulNeighbours[(uNSide + 1) % 3] != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[rclN._aulNeighbours[(uNSide + 1) % 3]].ReplaceNeighbour(ulNeighbour, + ulSize); + } - MeshFacet cNew; - cNew._aulPoints[0] = uPtInd; - cNew._aulPoints[1] = rclN._aulPoints[(uNSide+1)%3]; - cNew._aulPoints[2] = rclN._aulPoints[(uNSide+2)%3]; - cNew._aulNeighbours[0] = ulFacetPos; - cNew._aulNeighbours[1] = rclN._aulNeighbours[(uNSide+1)%3]; - cNew._aulNeighbours[2] = ulNeighbour; + MeshFacet cNew; + cNew._aulPoints[0] = uPtInd; + cNew._aulPoints[1] = rclN._aulPoints[(uNSide + 1) % 3]; + cNew._aulPoints[2] = rclN._aulPoints[(uNSide + 2) % 3]; + cNew._aulNeighbours[0] = ulFacetPos; + cNew._aulNeighbours[1] = rclN._aulNeighbours[(uNSide + 1) % 3]; + cNew._aulNeighbours[2] = ulNeighbour; - // adjust the facet - rclN._aulPoints[(uNSide+1)%3] = uPtInd; - rclN._aulNeighbours[(uNSide+1)%3] = ulSize; + // adjust the facet + rclN._aulPoints[(uNSide + 1) % 3] = uPtInd; + rclN._aulNeighbours[(uNSide + 1) % 3] = ulSize; - // insert new facet - _rclMesh._aclFacetArray.push_back(cNew); + // insert new facet + _rclMesh._aclFacetArray.push_back(cNew); } #if 0 @@ -1401,126 +1532,139 @@ void MeshTopoAlgorithm::SplitNeighbourFacet(FacetIndex ulFacetPos, unsigned shor bool MeshTopoAlgorithm::RemoveDegeneratedFacet(FacetIndex index) { - if (index >= _rclMesh._aclFacetArray.size()) - return false; - MeshFacet& rFace = _rclMesh._aclFacetArray[index]; - - // coincident corners (either topological or geometrical) - for (int i=0; i<3; i++) { - const MeshPoint& rE0 = _rclMesh._aclPointArray[rFace._aulPoints[i]]; - const MeshPoint& rE1 = _rclMesh._aclPointArray[rFace._aulPoints[(i+1)%3]]; - if (rE0 == rE1) { - FacetIndex uN1 = rFace._aulNeighbours[(i+1)%3]; - FacetIndex uN2 = rFace._aulNeighbours[(i+2)%3]; - if (uN2 != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[uN2].ReplaceNeighbour(index, uN1); - if (uN1 != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[uN1].ReplaceNeighbour(index, uN2); - - // isolate the face and remove it - rFace._aulNeighbours[0] = FACET_INDEX_MAX; - rFace._aulNeighbours[1] = FACET_INDEX_MAX; - rFace._aulNeighbours[2] = FACET_INDEX_MAX; - _rclMesh.DeleteFacet(index); - return true; + if (index >= _rclMesh._aclFacetArray.size()) { + return false; } - } + MeshFacet& rFace = _rclMesh._aclFacetArray[index]; - // We have a facet of the form - // P0 +----+------+P2 - // P1 - for (int j=0; j<3; j++) { - Base::Vector3f cVec1 = _rclMesh._aclPointArray[rFace._aulPoints[(j+1)%3]] - _rclMesh._aclPointArray[rFace._aulPoints[j]]; - Base::Vector3f cVec2 = _rclMesh._aclPointArray[rFace._aulPoints[(j+2)%3]] - _rclMesh._aclPointArray[rFace._aulPoints[j]]; + // coincident corners (either topological or geometrical) + for (int i = 0; i < 3; i++) { + const MeshPoint& rE0 = _rclMesh._aclPointArray[rFace._aulPoints[i]]; + const MeshPoint& rE1 = _rclMesh._aclPointArray[rFace._aulPoints[(i + 1) % 3]]; + if (rE0 == rE1) { + FacetIndex uN1 = rFace._aulNeighbours[(i + 1) % 3]; + FacetIndex uN2 = rFace._aulNeighbours[(i + 2) % 3]; + if (uN2 != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[uN2].ReplaceNeighbour(index, uN1); + } + if (uN1 != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[uN1].ReplaceNeighbour(index, uN2); + } - // adjust the neighbourhoods and point indices - if (cVec1 * cVec2 < 0.0f) { - FacetIndex uN1 = rFace._aulNeighbours[(j+1)%3]; - if (uN1 != FACET_INDEX_MAX) { - // get the neighbour and common edge side - MeshFacet& rNb = _rclMesh._aclFacetArray[uN1]; - unsigned short side = rNb.Side(index); - - // bend the point indices - rFace._aulPoints[(j+2)%3] = rNb._aulPoints[(side+2)%3]; - rNb._aulPoints[(side+1)%3] = rFace._aulPoints[j]; - - // set correct neighbourhood - FacetIndex uN2 = rFace._aulNeighbours[(j+2)%3]; - rNb._aulNeighbours[side] = uN2; - if (uN2 != FACET_INDEX_MAX) { - _rclMesh._aclFacetArray[uN2].ReplaceNeighbour(index, uN1); + // isolate the face and remove it + rFace._aulNeighbours[0] = FACET_INDEX_MAX; + rFace._aulNeighbours[1] = FACET_INDEX_MAX; + rFace._aulNeighbours[2] = FACET_INDEX_MAX; + _rclMesh.DeleteFacet(index); + return true; } - FacetIndex uN3 = rNb._aulNeighbours[(side+1)%3]; - rFace._aulNeighbours[(j+1)%3] = uN3; - if (uN3 != FACET_INDEX_MAX) { - _rclMesh._aclFacetArray[uN3].ReplaceNeighbour(uN1, index); - } - rNb._aulNeighbours[(side+1)%3] = index; - rFace._aulNeighbours[(j+2)%3] = uN1; - } - else - _rclMesh.DeleteFacet(index); - - return true; } - } - return false; + // We have a facet of the form + // P0 +----+------+P2 + // P1 + for (int j = 0; j < 3; j++) { + Base::Vector3f cVec1 = _rclMesh._aclPointArray[rFace._aulPoints[(j + 1) % 3]] + - _rclMesh._aclPointArray[rFace._aulPoints[j]]; + Base::Vector3f cVec2 = _rclMesh._aclPointArray[rFace._aulPoints[(j + 2) % 3]] + - _rclMesh._aclPointArray[rFace._aulPoints[j]]; + + // adjust the neighbourhoods and point indices + if (cVec1 * cVec2 < 0.0f) { + FacetIndex uN1 = rFace._aulNeighbours[(j + 1) % 3]; + if (uN1 != FACET_INDEX_MAX) { + // get the neighbour and common edge side + MeshFacet& rNb = _rclMesh._aclFacetArray[uN1]; + unsigned short side = rNb.Side(index); + + // bend the point indices + rFace._aulPoints[(j + 2) % 3] = rNb._aulPoints[(side + 2) % 3]; + rNb._aulPoints[(side + 1) % 3] = rFace._aulPoints[j]; + + // set correct neighbourhood + FacetIndex uN2 = rFace._aulNeighbours[(j + 2) % 3]; + rNb._aulNeighbours[side] = uN2; + if (uN2 != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[uN2].ReplaceNeighbour(index, uN1); + } + FacetIndex uN3 = rNb._aulNeighbours[(side + 1) % 3]; + rFace._aulNeighbours[(j + 1) % 3] = uN3; + if (uN3 != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[uN3].ReplaceNeighbour(uN1, index); + } + rNb._aulNeighbours[(side + 1) % 3] = index; + rFace._aulNeighbours[(j + 2) % 3] = uN1; + } + else { + _rclMesh.DeleteFacet(index); + } + + return true; + } + } + + return false; } bool MeshTopoAlgorithm::RemoveCorruptedFacet(FacetIndex index) { - if (index >= _rclMesh._aclFacetArray.size()) - return false; - MeshFacet& rFace = _rclMesh._aclFacetArray[index]; - - // coincident corners (topological) - for (int i=0; i<3; i++) { - if (rFace._aulPoints[i] == rFace._aulPoints[(i+1)%3]) { - FacetIndex uN1 = rFace._aulNeighbours[(i+1)%3]; - FacetIndex uN2 = rFace._aulNeighbours[(i+2)%3]; - if (uN2 != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[uN2].ReplaceNeighbour(index, uN1); - if (uN1 != FACET_INDEX_MAX) - _rclMesh._aclFacetArray[uN1].ReplaceNeighbour(index, uN2); - - // isolate the face and remove it - rFace._aulNeighbours[0] = FACET_INDEX_MAX; - rFace._aulNeighbours[1] = FACET_INDEX_MAX; - rFace._aulNeighbours[2] = FACET_INDEX_MAX; - _rclMesh.DeleteFacet(index); - return true; + if (index >= _rclMesh._aclFacetArray.size()) { + return false; } - } + MeshFacet& rFace = _rclMesh._aclFacetArray[index]; - return false; + // coincident corners (topological) + for (int i = 0; i < 3; i++) { + if (rFace._aulPoints[i] == rFace._aulPoints[(i + 1) % 3]) { + FacetIndex uN1 = rFace._aulNeighbours[(i + 1) % 3]; + FacetIndex uN2 = rFace._aulNeighbours[(i + 2) % 3]; + if (uN2 != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[uN2].ReplaceNeighbour(index, uN1); + } + if (uN1 != FACET_INDEX_MAX) { + _rclMesh._aclFacetArray[uN1].ReplaceNeighbour(index, uN2); + } + + // isolate the face and remove it + rFace._aulNeighbours[0] = FACET_INDEX_MAX; + rFace._aulNeighbours[1] = FACET_INDEX_MAX; + rFace._aulNeighbours[2] = FACET_INDEX_MAX; + _rclMesh.DeleteFacet(index); + return true; + } + } + + return false; } -void MeshTopoAlgorithm::FillupHoles(unsigned long length, int level, +void MeshTopoAlgorithm::FillupHoles(unsigned long length, + int level, AbstractPolygonTriangulator& cTria, - std::list >& aFailed) + std::list>& aFailed) { // get the mesh boundaries as an array of point indices - std::list > aBorders, aFillBorders; + std::list> aBorders, aFillBorders; MeshAlgorithm cAlgo(_rclMesh); cAlgo.GetMeshBorders(aBorders); // split boundary loops if needed cAlgo.SplitBoundaryLoops(aBorders); - for (const auto & aBorder : aBorders) { - if (aBorder.size()-1 <= length) // ignore boundary with too many edges + for (const auto& aBorder : aBorders) { + if (aBorder.size() - 1 <= length) { // ignore boundary with too many edges aFillBorders.push_back(aBorder); + } } - if (!aFillBorders.empty()) + if (!aFillBorders.empty()) { FillupHoles(level, cTria, aFillBorders, aFailed); + } } -void MeshTopoAlgorithm::FillupHoles(int level, AbstractPolygonTriangulator& cTria, - const std::list >& aBorders, - std::list >& aFailed) +void MeshTopoAlgorithm::FillupHoles(int level, + AbstractPolygonTriangulator& cTria, + const std::list>& aBorders, + std::list>& aFailed) { // get the facets to a point MeshRefPointToFacets cPt2Fac(_rclMesh); @@ -1529,25 +1673,27 @@ void MeshTopoAlgorithm::FillupHoles(int level, AbstractPolygonTriangulator& cTri MeshFacetArray newFacets; MeshPointArray newPoints; unsigned long numberOfOldPoints = _rclMesh._aclPointArray.size(); - for (const auto & aBorder : aBorders) { + for (const auto& aBorder : aBorders) { MeshFacetArray cFacets; MeshPointArray cPoints; std::vector bound = aBorder; if (cAlgo.FillupHole(bound, cTria, cFacets, cPoints, level, &cPt2Fac)) { - if (bound.front() == bound.back()) + if (bound.front() == bound.back()) { bound.pop_back(); - // the triangulation may produce additional points which we must take into account when appending to the mesh + } + // the triangulation may produce additional points which we must take into account when + // appending to the mesh if (cPoints.size() > bound.size()) { unsigned long countBoundaryPoints = bound.size(); unsigned long countDifference = cPoints.size() - countBoundaryPoints; MeshPointArray::_TIterator pt = cPoints.begin() + countBoundaryPoints; - for (unsigned long i=0; i= ctPoints || - newFacet._aulPoints[1] >= ctPoints || - newFacet._aulPoints[2] >= ctPoints) { + for (auto& newFacet : newFacets) { + if (newFacet._aulPoints[0] >= ctPoints || newFacet._aulPoints[1] >= ctPoints + || newFacet._aulPoints[2] >= ctPoints) { Base::Console().Log("Ignore invalid face <%d, %d, %d> (%d vertices)\n", - newFacet._aulPoints[0], newFacet._aulPoints[1], newFacet._aulPoints[2], ctPoints); + newFacet._aulPoints[0], + newFacet._aulPoints[1], + newFacet._aulPoints[2], + ctPoints); } else { addFacets.push_back(newFacet); @@ -1590,48 +1741,55 @@ void MeshTopoAlgorithm::FillupHoles(int level, AbstractPolygonTriangulator& cTri } void MeshTopoAlgorithm::FindHoles(unsigned long length, - std::list >& aBorders) const + std::list>& aBorders) const { - std::list > border; + std::list> border; MeshAlgorithm cAlgo(_rclMesh); cAlgo.GetMeshBorders(border); - for (const auto & it : border) { - if (it.size() <= length) + for (const auto& it : border) { + if (it.size() <= length) { aBorders.push_back(it); + } } } void MeshTopoAlgorithm::FindComponents(unsigned long count, std::vector& findIndices) { - std::vector > segments; - MeshComponents comp(_rclMesh); - comp.SearchForComponents(MeshComponents::OverEdge,segments); + std::vector> segments; + MeshComponents comp(_rclMesh); + comp.SearchForComponents(MeshComponents::OverEdge, segments); - for (const auto & segment : segments) { - if (segment.size() <= count) - findIndices.insert(findIndices.end(), segment.begin(), segment.end()); - } + for (const auto& segment : segments) { + if (segment.size() <= count) { + findIndices.insert(findIndices.end(), segment.begin(), segment.end()); + } + } } void MeshTopoAlgorithm::RemoveComponents(unsigned long count) { - std::vector removeFacets; - FindComponents(count, removeFacets); - if (!removeFacets.empty()) - _rclMesh.DeleteFacets(removeFacets); + std::vector removeFacets; + FindComponents(count, removeFacets); + if (!removeFacets.empty()) { + _rclMesh.DeleteFacets(removeFacets); + } } -void MeshTopoAlgorithm::HarmonizeNormals () +void MeshTopoAlgorithm::HarmonizeNormals() { - std::vector uIndices = MeshEvalOrientation(_rclMesh).GetIndices(); - for (FacetIndex index : uIndices) - _rclMesh._aclFacetArray[index].FlipNormal(); + std::vector uIndices = MeshEvalOrientation(_rclMesh).GetIndices(); + for (FacetIndex index : uIndices) { + _rclMesh._aclFacetArray[index].FlipNormal(); + } } -void MeshTopoAlgorithm::FlipNormals () +void MeshTopoAlgorithm::FlipNormals() { - for (MeshFacetArray::_TIterator i = _rclMesh._aclFacetArray.begin(); i < _rclMesh._aclFacetArray.end(); ++i) - i->FlipNormal(); + for (MeshFacetArray::_TIterator i = _rclMesh._aclFacetArray.begin(); + i < _rclMesh._aclFacetArray.end(); + ++i) { + i->FlipNormal(); + } } // --------------------------------------------------------------------------- @@ -1659,80 +1817,87 @@ void MeshTopoAlgorithm::FlipNormals () * See also http://max-limper.de/publications/Euler/ */ -MeshComponents::MeshComponents( const MeshKernel& rclMesh ) -: _rclMesh(rclMesh) +MeshComponents::MeshComponents(const MeshKernel& rclMesh) + : _rclMesh(rclMesh) +{} + +void MeshComponents::SearchForComponents(TMode tMode, + std::vector>& aclT) const { + // all facets + std::vector aulAllFacets(_rclMesh.CountFacets()); + FacetIndex k = 0; + for (FacetIndex& aulAllFacet : aulAllFacets) { + aulAllFacet = k++; + } + + SearchForComponents(tMode, aulAllFacets, aclT); } -void MeshComponents::SearchForComponents(TMode tMode, std::vector >& aclT) const +void MeshComponents::SearchForComponents(TMode tMode, + const std::vector& aSegment, + std::vector>& aclT) const { - // all facets - std::vector aulAllFacets(_rclMesh.CountFacets()); - FacetIndex k = 0; - for (FacetIndex & aulAllFacet : aulAllFacets) - aulAllFacet = k++; + FacetIndex ulStartFacet; - SearchForComponents( tMode, aulAllFacets, aclT ); -} + if (_rclMesh.CountFacets() == 0) { + return; + } -void MeshComponents::SearchForComponents(TMode tMode, const std::vector& aSegment, std::vector >& aclT) const -{ - FacetIndex ulStartFacet; + // reset VISIT flags + MeshAlgorithm cAlgo(_rclMesh); + cAlgo.SetFacetFlag(MeshFacet::VISIT); + cAlgo.ResetFacetsFlag(aSegment, MeshFacet::VISIT); - if (_rclMesh.CountFacets() == 0) - return; + const MeshFacetArray& rFAry = _rclMesh.GetFacets(); + MeshFacetArray::_TConstIterator iTri = rFAry.begin(); + MeshFacetArray::_TConstIterator iBeg = rFAry.begin(); + MeshFacetArray::_TConstIterator iEnd = rFAry.end(); - // reset VISIT flags - MeshAlgorithm cAlgo(_rclMesh); - cAlgo.SetFacetFlag(MeshFacet::VISIT); - cAlgo.ResetFacetsFlag(aSegment, MeshFacet::VISIT); - - const MeshFacetArray& rFAry = _rclMesh.GetFacets(); - MeshFacetArray::_TConstIterator iTri = rFAry.begin(); - MeshFacetArray::_TConstIterator iBeg = rFAry.begin(); - MeshFacetArray::_TConstIterator iEnd = rFAry.end(); - - // start from the first not visited facet - unsigned long ulVisited = cAlgo.CountFacetFlag(MeshFacet::VISIT); - MeshIsNotFlag flag; - iTri = std::find_if(iTri, iEnd, [flag](const MeshFacet& f) { - return flag(f, MeshFacet::VISIT); - }); - ulStartFacet = iTri - iBeg; - - // visitor - std::vector aclComponent; - std::vector > aclConnectComp; - MeshTopFacetVisitor clFVisitor( aclComponent ); - - while ( ulStartFacet != FACET_INDEX_MAX ) - { - // collect all facets of a component - aclComponent.clear(); - if (tMode == OverEdge) - ulVisited += _rclMesh.VisitNeighbourFacets(clFVisitor, ulStartFacet); - else if (tMode == OverPoint) - ulVisited += _rclMesh.VisitNeighbourFacetsOverCorners(clFVisitor, ulStartFacet); - - // get also start facet - aclComponent.push_back(ulStartFacet); - aclConnectComp.push_back(aclComponent); - - // if the mesh consists of several topologic independent components - // We can search from position 'iTri' on because all elements _before_ are already visited - // what we know from the previous iteration. + // start from the first not visited facet + unsigned long ulVisited = cAlgo.CountFacetFlag(MeshFacet::VISIT); + MeshIsNotFlag flag; iTri = std::find_if(iTri, iEnd, [flag](const MeshFacet& f) { return flag(f, MeshFacet::VISIT); }); + ulStartFacet = iTri - iBeg; - if (iTri < iEnd) - ulStartFacet = iTri - iBeg; - else - ulStartFacet = FACET_INDEX_MAX; - } + // visitor + std::vector aclComponent; + std::vector> aclConnectComp; + MeshTopFacetVisitor clFVisitor(aclComponent); - // sort components by size (descending order) - std::sort(aclConnectComp.begin(), aclConnectComp.end(), CNofFacetsCompare()); - aclT = aclConnectComp; - boost::ignore_unused(ulVisited); + while (ulStartFacet != FACET_INDEX_MAX) { + // collect all facets of a component + aclComponent.clear(); + if (tMode == OverEdge) { + ulVisited += _rclMesh.VisitNeighbourFacets(clFVisitor, ulStartFacet); + } + else if (tMode == OverPoint) { + ulVisited += _rclMesh.VisitNeighbourFacetsOverCorners(clFVisitor, ulStartFacet); + } + + // get also start facet + aclComponent.push_back(ulStartFacet); + aclConnectComp.push_back(aclComponent); + + // if the mesh consists of several topologic independent components + // We can search from position 'iTri' on because all elements _before_ are already visited + // what we know from the previous iteration. + iTri = std::find_if(iTri, iEnd, [flag](const MeshFacet& f) { + return flag(f, MeshFacet::VISIT); + }); + + if (iTri < iEnd) { + ulStartFacet = iTri - iBeg; + } + else { + ulStartFacet = FACET_INDEX_MAX; + } + } + + // sort components by size (descending order) + std::sort(aclConnectComp.begin(), aclConnectComp.end(), CNofFacetsCompare()); + aclT = aclConnectComp; + boost::ignore_unused(ulVisited); } diff --git a/src/Mod/Mesh/App/Core/TopoAlgorithm.h b/src/Mod/Mesh/App/Core/TopoAlgorithm.h index 9813067db2..02d140ac23 100644 --- a/src/Mod/Mesh/App/Core/TopoAlgorithm.h +++ b/src/Mod/Mesh/App/Core/TopoAlgorithm.h @@ -31,7 +31,8 @@ #include "MeshKernel.h" -namespace MeshCore { +namespace MeshCore +{ class AbstractPolygonTriangulator; struct EdgeCollapse; @@ -46,8 +47,8 @@ class MeshExport MeshTopoAlgorithm { public: // construction/destruction - explicit MeshTopoAlgorithm (MeshKernel &rclM); - ~MeshTopoAlgorithm (); + explicit MeshTopoAlgorithm(MeshKernel& rclM); + ~MeshTopoAlgorithm(); public: /** @name Topological Operations */ @@ -57,7 +58,7 @@ public: * triangles. The given point must lie inside the triangle not outside or on * an edge. */ - bool InsertVertex(FacetIndex ulFacetPos, const Base::Vector3f& rclPoint); + bool InsertVertex(FacetIndex ulFacetPos, const Base::Vector3f& rclPoint); /** * This method is provided for convenience. It inserts a new vertex to the * mesh and tries to swap the common edges of the newly created facets with @@ -67,8 +68,8 @@ public: * edges to build more well-formed triangles. * @see InsertVertex(), ShouldSwapEdge(), SwapEdge(). */ - bool InsertVertexAndSwapEdge(FacetIndex ulFacetPos, const Base::Vector3f& rclPoint, - float fMaxAngle); + bool + InsertVertexAndSwapEdge(FacetIndex ulFacetPos, const Base::Vector3f& rclPoint, float fMaxAngle); /** * Swaps the common edge of two adjacent facets even if the operation might * be illegal. To be sure that this operation is legal, check either with @@ -85,16 +86,14 @@ public: * that two new facets get created. If \a rP is coincident with a corner point * nothing happens. */ - bool SplitEdge(FacetIndex ulFacetPos, FacetIndex ulNeighbour, - const Base::Vector3f& rP); + bool SplitEdge(FacetIndex ulFacetPos, FacetIndex ulNeighbour, const Base::Vector3f& rP); /** * Splits the facet with index \a ulFacetPos on the edge side \a uSide into * two facets. This side must be an open edge otherwise nothing is done. The * point \a rP must be near to this edge and must not be coincident with any * corner vertices of the facet. */ - bool SplitOpenEdge(FacetIndex ulFacetPos, unsigned short uSide, - const Base::Vector3f& rP); + bool SplitOpenEdge(FacetIndex ulFacetPos, unsigned short uSide, const Base::Vector3f& rP); /** * Splits the facet with index \a ulFacetPos into up to three facets. The points * \a rP1 and \a rP2 should lie on two different edges of the facet. This method @@ -103,8 +102,7 @@ public: * is coincident with a corner point then the facet is split into two facets. * If both points are coincident with corner points of this facet nothing is done. */ - void SplitFacet(FacetIndex ulFacetPos, const Base::Vector3f& rP1, - const Base::Vector3f& rP2); + void SplitFacet(FacetIndex ulFacetPos, const Base::Vector3f& rP1, const Base::Vector3f& rP2); /** * Collapse a vertex. At the moment only removing inner vertexes referenced * by three facets is supposrted. @@ -217,8 +215,7 @@ public: * facets is decreased and if the angle between the facet normals does * not exceed \a fMaxAngle. */ - bool ShouldSwapEdge(FacetIndex ulFacetPos, FacetIndex ulNeighbour, - float fMaxAngle) const; + bool ShouldSwapEdge(FacetIndex ulFacetPos, FacetIndex ulNeighbour, float fMaxAngle) const; /** Computes a value for the benefit of swapping the edge. */ float SwapEdgeBenefit(FacetIndex f, int e) const; /** @@ -240,21 +237,22 @@ public: * needs to be done then the points of the neighbours of \a level rings will be used. * Holes for which the triangulation failed are returned in \a aFailed. */ - void FillupHoles(unsigned long length, int level, - AbstractPolygonTriangulator&, - std::list >& aFailed); + void FillupHoles(unsigned long length, + int level, + AbstractPolygonTriangulator&, + std::list>& aFailed); /** * This is an overloaded method provided for convenience. It takes as first argument * the boundaries which must be filled up. */ - void FillupHoles(int level, AbstractPolygonTriangulator&, - const std::list >& aBorders, - std::list >& aFailed); + void FillupHoles(int level, + AbstractPolygonTriangulator&, + const std::list>& aBorders, + std::list>& aFailed); /** * Find holes which consists of up to \a length edges. */ - void FindHoles(unsigned long length, - std::list >& aBorders) const; + void FindHoles(unsigned long length, std::list>& aBorders) const; /** * Find topologic independent components with maximum \a count facets * and returns an array of the indices. @@ -267,11 +265,11 @@ public: /** * Harmonizes the normals. */ - void HarmonizeNormals (); + void HarmonizeNormals(); /** * Flips the normals. */ - void FlipNormals (); + void FlipNormals(); /** * Caching facility. */ @@ -282,32 +280,33 @@ private: /** * Splits the neighbour facet of \a ulFacetPos on side \a uSide. */ - void SplitNeighbourFacet(FacetIndex ulFacetPos, unsigned short uSide, - const Base::Vector3f rPoint); - void SplitFacetOnOneEdge(FacetIndex ulFacetPos, - const Base::Vector3f& rP1); + void + SplitNeighbourFacet(FacetIndex ulFacetPos, unsigned short uSide, const Base::Vector3f rPoint); + void SplitFacetOnOneEdge(FacetIndex ulFacetPos, const Base::Vector3f& rP1); void SplitFacetOnTwoEdges(FacetIndex ulFacetPos, const Base::Vector3f& rP1, const Base::Vector3f& rP2); - void SplitFacet(FacetIndex ulFacetPos, PointIndex P1, - PointIndex P2, PointIndex Pn); + void SplitFacet(FacetIndex ulFacetPos, PointIndex P1, PointIndex P2, PointIndex Pn); void AddFacet(PointIndex P1, PointIndex P2, PointIndex P3); - void AddFacet(PointIndex P1, PointIndex P2, PointIndex P3, - FacetIndex N1, FacetIndex N2, FacetIndex N3); + void AddFacet(PointIndex P1, + PointIndex P2, + PointIndex P3, + FacetIndex N1, + FacetIndex N2, + FacetIndex N3); void HarmonizeNeighbours(FacetIndex facet1, FacetIndex facet2); void HarmonizeNeighbours(const std::vector& ulFacets); /** * Returns all facets that references the point index \a uPointPos. \a uFacetPos * is a facet that must reference this point and is added to the list as well. */ - std::vector GetFacetsToPoint(FacetIndex uFacetPos, - PointIndex uPointPos) const; + std::vector GetFacetsToPoint(FacetIndex uFacetPos, PointIndex uPointPos) const; /** \internal */ - PointIndex GetOrAddIndex (const MeshPoint &rclPoint); + PointIndex GetOrAddIndex(const MeshPoint& rclPoint); private: MeshKernel& _rclMesh; - bool _needsCleanup{false}; + bool _needsCleanup {false}; struct Vertex_Less { @@ -315,8 +314,8 @@ private: }; // cache - using tCache = std::map; - tCache* _cache{nullptr}; + using tCache = std::map; + tCache* _cache {nullptr}; }; /** @@ -328,38 +327,43 @@ private: class MeshExport MeshComponents { public: - enum TMode {OverEdge, OverPoint}; + enum TMode + { + OverEdge, + OverPoint + }; - explicit MeshComponents( const MeshKernel& rclMesh ); + explicit MeshComponents(const MeshKernel& rclMesh); /** * Searches for 'isles' of the mesh. If \a tMode is \a OverEdge then facets * sharing the same edge are regarded as connected, if \a tMode is \a OverPoint * then facets sharing a common point are regarded as connected. */ - void SearchForComponents(TMode tMode, std::vector >& aclT) const; + void SearchForComponents(TMode tMode, std::vector>& aclT) const; /** * Does basically the same as the method above escept that only the faces in * \a aSegment are regarded. */ - void SearchForComponents(TMode tMode, const std::vector& aSegment, - std::vector >& aclT) const; + void SearchForComponents(TMode tMode, + const std::vector& aSegment, + std::vector>& aclT) const; protected: // for sorting of elements struct CNofFacetsCompare { - bool operator () (const std::vector &rclC1, - const std::vector &rclC2) + bool operator()(const std::vector& rclC1, const std::vector& rclC2) { return rclC1.size() > rclC2.size(); } }; + protected: const MeshKernel& _rclMesh; }; -} // namespace MeshCore +} // namespace MeshCore -#endif // MESH_TOPOALGORITHM_H +#endif // MESH_TOPOALGORITHM_H diff --git a/src/Mod/Mesh/App/Core/Triangulation.cpp b/src/Mod/Mesh/App/Core/Triangulation.cpp index 0816b40863..20049971b3 100644 --- a/src/Mod/Mesh/App/Core/Triangulation.cpp +++ b/src/Mod/Mesh/App/Core/Triangulation.cpp @@ -22,16 +22,16 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include #include #include -#include "Triangulation.h" #include "Approximation.h" #include "MeshKernel.h" +#include "Triangulation.h" using namespace MeshCore; @@ -47,8 +47,7 @@ bool TriangulationVerifier::Accept(const Base::Vector3f& n, return (ref_dist * tri_dist <= 0.0f); } -bool TriangulationVerifier::MustFlip(const Base::Vector3f& n1, - const Base::Vector3f& n2) const +bool TriangulationVerifier::MustFlip(const Base::Vector3f& n1, const Base::Vector3f& n2) const { return n1.Dot(n2) <= 0.0f; } @@ -65,8 +64,7 @@ bool TriangulationVerifierV2::Accept(const Base::Vector3f& n, return true; } -bool TriangulationVerifierV2::MustFlip(const Base::Vector3f& n1, - const Base::Vector3f& n2) const +bool TriangulationVerifierV2::MustFlip(const Base::Vector3f& n1, const Base::Vector3f& n2) const { float dot = n1.Dot(n2); (void)dot; @@ -101,8 +99,9 @@ void AbstractPolygonTriangulator::SetPolygon(const std::vector& { this->_points = raclPoints; if (!this->_points.empty()) { - if (this->_points.front() == this->_points.back()) + if (this->_points.front() == this->_points.back()) { this->_points.pop_back(); + } } } @@ -115,9 +114,12 @@ float AbstractPolygonTriangulator::GetLength() const { float len = 0.0f; if (_points.size() > 2) { - for (std::vector::const_iterator it = _points.begin(); it != _points.end();++it) { + for (std::vector::const_iterator it = _points.begin(); it != _points.end(); + ++it) { std::vector::const_iterator jt = it + 1; - if (jt == _points.end()) jt = _points.begin(); + if (jt == _points.end()) { + jt = _points.begin(); + } len += Base::Distance(*it, *jt); } } @@ -130,19 +132,22 @@ std::vector AbstractPolygonTriangulator::AddedPoints() const // Apply the inverse transformation to project back to world coordinates std::vector added; added.reserve(_newpoints.size()); - for (auto point : _newpoints) + for (auto point : _newpoints) { added.push_back(_inverse * point); + } return added; } Base::Matrix4D AbstractPolygonTriangulator::GetTransformToFitPlane() const { PlaneFit planeFit; - for (auto point : _points) + for (auto point : _points) { planeFit.AddPoint(point); + } - if (planeFit.Fit() >= FLOAT_MAX) + if (planeFit.Fit() >= FLOAT_MAX) { throw Base::RuntimeError("Plane fit failed"); + } Base::Vector3f bs = planeFit.GetBase(); Base::Vector3f ex = planeFit.GetDirU(); @@ -183,8 +188,9 @@ std::vector AbstractPolygonTriangulator::ProjectToFitPlane() Base::Vector3f ey(static_cast(_inverse[0][1]), static_cast(_inverse[1][1]), static_cast(_inverse[2][1])); - for (auto & jt : proj) + for (auto& jt : proj) { jt.TransformToCoordinateSystem(bs, ex, ey); + } return proj; } @@ -211,8 +217,9 @@ void AbstractPolygonTriangulator::PostProcessing(const std::vector= uMinPts && polyFit.Fit() < FLOAT_MAX) { - for (auto & newpoint : _newpoints) + for (auto& newpoint : _newpoints) { newpoint.z = static_cast(polyFit.Value(newpoint.x, newpoint.y)); + } } } @@ -230,11 +237,15 @@ bool AbstractPolygonTriangulator::TriangulatePolygon() { try { if (!this->_indices.empty() && this->_points.size() != this->_indices.size()) { - Base::Console().Log("Triangulation: %d points <> %d indices\n", _points.size(), _indices.size()); + Base::Console().Log("Triangulation: %d points <> %d indices\n", + _points.size(), + _indices.size()); return false; } bool ok = Triangulate(); - if (ok) Done(); + if (ok) { + Done(); + } return ok; } catch (const Base::Exception& e) { @@ -264,8 +275,7 @@ void AbstractPolygonTriangulator::Discard() } void AbstractPolygonTriangulator::Reset() -{ -} +{} void AbstractPolygonTriangulator::Done() { @@ -286,33 +296,34 @@ bool EarClippingTriangulator::Triangulate() std::vector result; // Invoke the triangulator to triangulate this polygon. - Triangulate::Process(pts,result); + Triangulate::Process(pts, result); // print out the results. - size_t tcount = result.size()/3; + size_t tcount = result.size() / 3; - bool ok = tcount+2 == _points.size(); - if (tcount > _points.size()) - return false; // no valid triangulation + bool ok = tcount + 2 == _points.size(); + if (tcount > _points.size()) { + return false; // no valid triangulation + } MeshGeomFacet clFacet; MeshFacet clTopFacet; - for (size_t i=0; i &contour) +float EarClippingTriangulator::Triangulate::Area(const std::vector& contour) { int n = contour.size(); - float A=0.0f; + float A = 0.0f; - for(int p=n-1,q=0; q= FLOAT_EPS) && (bCROSScp >= FLOAT_EPS) && (cCROSSap >= FLOAT_EPS)); } -bool EarClippingTriangulator::Triangulate::Snip(const std::vector &contour, - int u,int v,int w,int n,int *V) +bool EarClippingTriangulator::Triangulate::Snip(const std::vector& contour, + int u, + int v, + int w, + int n, + int* V) { int p; float Ax, Ay, Bx, By, Cx, Cy, Px, Py; @@ -374,15 +400,19 @@ bool EarClippingTriangulator::Triangulate::Snip(const std::vector (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax)))) + if (FLOAT_EPS > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax)))) { return false; + } - for (p=0;p &contour, - std::vector &result) +bool EarClippingTriangulator::Triangulate::Process(const std::vector& contour, + std::vector& result) { /* allocate and initialize list of Vertices in polygon */ int n = contour.size(); - if ( n < 3 ) + if (n < 3) { return false; + } - int *V = new int[n]; + int* V = new int[n]; /* we want a counter-clockwise polygon in V */ if (0.0f < Area(contour)) { - for (int v=0; v2; ) { + for (int v = nv - 1; nv > 2;) { /* if we loop, it is probably a non-simple polygon */ if (0 >= (count--)) { //** Triangulate: ERROR - probable bad polygon! - delete [] V; + delete[] V; return false; } /* three consecutive vertices in current polygon, */ - int u = v ; if (nv <= u) u = 0; /* previous */ - v = u+1; if (nv <= v) v = 0; /* new v */ - int w = v+1; if (nv <= w) w = 0; /* next */ + int u = v; + if (nv <= u) { + u = 0; /* previous */ + } + v = u + 1; + if (nv <= v) { + v = 0; /* new v */ + } + int w = v + 1; + if (nv <= w) { + w = 0; /* next */ + } - if (Snip(contour,u,v,w,nv,V)) { - int a,b,c,s,t; + if (Snip(contour, u, v, w, nv, V)) { + int a, b, c, s, t; /* true names of the vertices */ - a = V[u]; b = V[v]; c = V[w]; + a = V[u]; + b = V[v]; + c = V[w]; /* output Triangle */ - result.push_back( a ); - result.push_back( b ); - result.push_back( c ); + result.push_back(a); + result.push_back(b); + result.push_back(c); /* remove v from remaining polygon */ - for(s=v,t=v+1;t, std::vector > aEdge2Face; + std::map, std::vector> aEdge2Face; for (std::vector::iterator pI = _facets.begin(); pI != _facets.end(); ++pI) { for (int i = 0; i < 3; i++) { - PointIndex ulPt0 = std::min(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); - PointIndex ulPt1 = std::max(pI->_aulPoints[i], pI->_aulPoints[(i+1)%3]); + PointIndex ulPt0 = std::min(pI->_aulPoints[i], pI->_aulPoints[(i + 1) % 3]); + PointIndex ulPt1 = std::max(pI->_aulPoints[i], pI->_aulPoints[(i + 1) % 3]); // ignore borderlines of the polygon - if ((ulPt1-ulPt0)%(_points.size()-1) > 1) - aEdge2Face[std::pair(ulPt0, ulPt1)].push_back(pI - _facets.begin()); + if ((ulPt1 - ulPt0) % (_points.size() - 1) > 1) { + aEdge2Face[std::pair(ulPt0, ulPt1)].push_back( + pI - _facets.begin()); + } } } // fill up this list with all internal edges and perform swap edges until this list is empty - std::list > aEdgeList; - std::map, std::vector >::iterator pE; - for (pE = aEdge2Face.begin(); pE != aEdge2Face.end(); ++pE) + std::list> aEdgeList; + std::map, std::vector>::iterator pE; + for (pE = aEdge2Face.begin(); pE != aEdge2Face.end(); ++pE) { aEdgeList.push_back(pE->first); + } // to be sure to avoid an endless loop size_t uMaxIter = 5 * aEdge2Face.size(); @@ -497,80 +548,95 @@ bool QuasiDelaunayTriangulator::Triangulate() uMaxIter--; // get the adjacent facets to this edge - pE = aEdge2Face.find( aEdge ); + pE = aEdge2Face.find(aEdge); // this edge has been removed some iterations before - if (pE == aEdge2Face.end()) + if (pE == aEdge2Face.end()) { continue; + } MeshFacet& rF1 = _facets[pE->second[0]]; MeshFacet& rF2 = _facets[pE->second[1]]; unsigned short side1 = rF1.Side(aEdge.first, aEdge.second); Base::Vector3f cP1 = _points[rF1._aulPoints[side1]]; - Base::Vector3f cP2 = _points[rF1._aulPoints[(side1+1)%3]]; - Base::Vector3f cP3 = _points[rF1._aulPoints[(side1+2)%3]]; + Base::Vector3f cP2 = _points[rF1._aulPoints[(side1 + 1) % 3]]; + Base::Vector3f cP3 = _points[rF1._aulPoints[(side1 + 2) % 3]]; unsigned short side2 = rF2.Side(aEdge.first, aEdge.second); - Base::Vector3f cP4 = _points[rF2._aulPoints[(side2+2)%3]]; + Base::Vector3f cP4 = _points[rF2._aulPoints[(side2 + 2) % 3]]; - MeshGeomFacet cT1(cP1, cP2, cP3); float fMax1 = cT1.MaximumAngle(); - MeshGeomFacet cT2(cP2, cP1, cP4); float fMax2 = cT2.MaximumAngle(); - MeshGeomFacet cT3(cP4, cP3, cP1); float fMax3 = cT3.MaximumAngle(); - MeshGeomFacet cT4(cP3, cP4, cP2); float fMax4 = cT4.MaximumAngle(); + MeshGeomFacet cT1(cP1, cP2, cP3); + float fMax1 = cT1.MaximumAngle(); + MeshGeomFacet cT2(cP2, cP1, cP4); + float fMax2 = cT2.MaximumAngle(); + MeshGeomFacet cT3(cP4, cP3, cP1); + float fMax3 = cT3.MaximumAngle(); + MeshGeomFacet cT4(cP3, cP4, cP2); + float fMax4 = cT4.MaximumAngle(); float fMax12 = std::max(fMax1, fMax2); float fMax34 = std::max(fMax3, fMax4); // We must make sure that the two adjacent triangles builds a convex polygon, otherwise // the swap edge operation is illegal - Base::Vector3f cU = cP2-cP1; - Base::Vector3f cV = cP4-cP3; + Base::Vector3f cU = cP2 - cP1; + Base::Vector3f cV = cP4 - cP3; // build a helper plane through cP1 that must separate cP3 and cP4 Base::Vector3f cN1 = (cU % cV) % cU; - if (((cP3-cP1)*cN1)*((cP4-cP1)*cN1) >= 0.0f) - continue; // not convex + if (((cP3 - cP1) * cN1) * ((cP4 - cP1) * cN1) >= 0.0f) { + continue; // not convex + } // build a helper plane through cP3 that must separate cP1 and cP2 Base::Vector3f cN2 = (cU % cV) % cV; - if (((cP1-cP3)*cN2)*((cP2-cP3)*cN2) >= 0.0f) - continue; // not convex + if (((cP1 - cP3) * cN2) * ((cP2 - cP3) * cN2) >= 0.0f) { + continue; // not convex + } // ok, here we should perform a swap edge to minimize the maximum angle if (fMax12 > fMax34) { - rF1._aulPoints[(side1+1)%3] = rF2._aulPoints[(side2+2)%3]; - rF2._aulPoints[(side2+1)%3] = rF1._aulPoints[(side1+2)%3]; + rF1._aulPoints[(side1 + 1) % 3] = rF2._aulPoints[(side2 + 2) % 3]; + rF2._aulPoints[(side2 + 1) % 3] = rF1._aulPoints[(side1 + 2) % 3]; // adjust the edge list - for (int i=0; i<3; i++) { - std::map, std::vector >::iterator it; + for (int i = 0; i < 3; i++) { + std::map, std::vector>::iterator it; // first facet - PointIndex ulPt0 = std::min(rF1._aulPoints[i], rF1._aulPoints[(i+1)%3]); - PointIndex ulPt1 = std::max(rF1._aulPoints[i], rF1._aulPoints[(i+1)%3]); - it = aEdge2Face.find( std::make_pair(ulPt0, ulPt1) ); + PointIndex ulPt0 = + std::min(rF1._aulPoints[i], rF1._aulPoints[(i + 1) % 3]); + PointIndex ulPt1 = + std::max(rF1._aulPoints[i], rF1._aulPoints[(i + 1) % 3]); + it = aEdge2Face.find(std::make_pair(ulPt0, ulPt1)); if (it != aEdge2Face.end()) { - if (it->second[0] == pE->second[1]) + if (it->second[0] == pE->second[1]) { it->second[0] = pE->second[0]; - else if (it->second[1] == pE->second[1]) + } + else if (it->second[1] == pE->second[1]) { it->second[1] = pE->second[0]; + } aEdgeList.push_back(it->first); } // second facet - ulPt0 = std::min(rF2._aulPoints[i], rF2._aulPoints[(i+1)%3]); - ulPt1 = std::max(rF2._aulPoints[i], rF2._aulPoints[(i+1)%3]); - it = aEdge2Face.find( std::make_pair(ulPt0, ulPt1) ); + ulPt0 = std::min(rF2._aulPoints[i], rF2._aulPoints[(i + 1) % 3]); + ulPt1 = std::max(rF2._aulPoints[i], rF2._aulPoints[(i + 1) % 3]); + it = aEdge2Face.find(std::make_pair(ulPt0, ulPt1)); if (it != aEdge2Face.end()) { - if (it->second[0] == pE->second[0]) + if (it->second[0] == pE->second[0]) { it->second[0] = pE->second[1]; - else if (it->second[1] == pE->second[0]) + } + else if (it->second[1] == pE->second[0]) { it->second[1] = pE->second[1]; + } aEdgeList.push_back(it->first); } } // Now we must remove the edge and replace it through the new edge - PointIndex ulPt0 = std::min(rF1._aulPoints[(side1+1)%3], rF2._aulPoints[(side2+1)%3]); - PointIndex ulPt1 = std::max(rF1._aulPoints[(side1+1)%3], rF2._aulPoints[(side2+1)%3]); + PointIndex ulPt0 = std::min(rF1._aulPoints[(side1 + 1) % 3], + rF2._aulPoints[(side2 + 1) % 3]); + PointIndex ulPt1 = std::max(rF1._aulPoints[(side1 + 1) % 3], + rF2._aulPoints[(side2 + 1) % 3]); std::pair aNewEdge = std::make_pair(ulPt0, ulPt1); aEdge2Face[aNewEdge] = pE->second; aEdge2Face.erase(pE); @@ -582,8 +648,10 @@ bool QuasiDelaunayTriangulator::Triangulate() // ------------------------------------------------------------- -namespace MeshCore { -namespace Triangulation { +namespace MeshCore +{ +namespace Triangulation +{ struct Vertex2d_Less { bool operator()(const Base::Vector3f& p, const Base::Vector3f& q) const @@ -605,15 +673,16 @@ struct Vertex2d_EqualTo { bool operator()(const Base::Vector3f& p, const Base::Vector3f& q) const { - if (fabs(p.x - q.x) < MeshDefinitions::_fMinPointDistanceD1 && - fabs(p.y - q.y) < MeshDefinitions::_fMinPointDistanceD1) + if (fabs(p.x - q.x) < MeshDefinitions::_fMinPointDistanceD1 + && fabs(p.y - q.y) < MeshDefinitions::_fMinPointDistanceD1) { return true; + } return false; } }; -} -} +} // namespace Triangulation +} // namespace MeshCore DelaunayTriangulator::DelaunayTriangulator() = default; @@ -625,39 +694,44 @@ bool DelaunayTriangulator::Triangulate() // sort the points ascending x,y coordinates std::sort(aPoints.begin(), aPoints.end(), Triangulation::Vertex2d_Less()); // if there are two adjacent points whose distance is less then an epsilon - if (std::adjacent_find(aPoints.begin(), aPoints.end(), - Triangulation::Vertex2d_EqualTo()) < aPoints.end()) + if (std::adjacent_find(aPoints.begin(), aPoints.end(), Triangulation::Vertex2d_EqualTo()) + < aPoints.end()) { return false; + } _facets.clear(); _triangles.clear(); std::vector akVertex; akVertex.reserve(_points.size()); - for (const auto & point : _points) { + for (const auto& point : _points) { akVertex.emplace_back(static_cast(point.x), static_cast(point.y)); } - Wm4::Delaunay2d del(static_cast(akVertex.size()), &(akVertex[0]), 0.001, false, Wm4::Query::QT_INT64); + Wm4::Delaunay2d del(static_cast(akVertex.size()), + &(akVertex[0]), + 0.001, + false, + Wm4::Query::QT_INT64); int iTQuantity = del.GetSimplexQuantity(); - std::vector aiTVertex(static_cast(3*iTQuantity)); + std::vector aiTVertex(static_cast(3 * iTQuantity)); bool succeeded = false; if (iTQuantity > 0) { - size_t uiSize = static_cast(3*iTQuantity)*sizeof(int); - Wm4::System::Memcpy(&(aiTVertex[0]),uiSize,del.GetIndices(),uiSize); + size_t uiSize = static_cast(3 * iTQuantity) * sizeof(int); + Wm4::System::Memcpy(&(aiTVertex[0]), uiSize, del.GetIndices(), uiSize); // If H is the number of hull edges and N is the number of vertices, // then the triangulation must have 2*N-2-H triangles and 3*N-3-H // edges. int iEQuantity = 0; int* aiIndex = nullptr; - del.GetHull(iEQuantity,aiIndex); + del.GetHull(iEQuantity, aiIndex); int iUniqueVQuantity = del.GetUniqueVertexQuantity(); - int iTVerify = 2*iUniqueVQuantity - 2 - iEQuantity; + int iTVerify = 2 * iUniqueVQuantity - 2 - iEQuantity; (void)iTVerify; // avoid warning in release build succeeded = (iTVerify == iTQuantity); - int iEVerify = 3*iUniqueVQuantity - 3 - iEQuantity; + int iEVerify = 3 * iUniqueVQuantity - 3 - iEQuantity; (void)iEVerify; // avoid warning about unused variable delete[] aiIndex; } @@ -665,8 +739,8 @@ bool DelaunayTriangulator::Triangulate() MeshGeomFacet triangle; MeshFacet facet; for (int i = 0; i < iTQuantity; i++) { - for (int j=0; j<3; j++) { - size_t index = static_cast(aiTVertex[static_cast(3*i+j)]); + for (int j = 0; j < 3; j++) { + size_t index = static_cast(aiTVertex[static_cast(3 * i + j)]); facet._aulPoints[j] = static_cast(index); triangle._aclPoints[j].x = static_cast(akVertex[index].X()); triangle._aclPoints[j].y = static_cast(akVertex[index].Y()); @@ -693,9 +767,9 @@ bool FlatTriangulator::Triangulate() // sort the points ascending x,y coordinates std::sort(tmp.begin(), tmp.end(), Triangulation::Vertex2d_Less()); // if there are two adjacent points whose distance is less then an epsilon - if (std::adjacent_find(tmp.begin(), tmp.end(), - Triangulation::Vertex2d_EqualTo()) < tmp.end() ) + if (std::adjacent_find(tmp.begin(), tmp.end(), Triangulation::Vertex2d_EqualTo()) < tmp.end()) { return false; + } _facets.clear(); _triangles.clear(); @@ -711,13 +785,12 @@ bool FlatTriangulator::Triangulate() } void FlatTriangulator::PostProcessing(const std::vector&) -{ -} +{} // ------------------------------------------------------------- ConstraintDelaunayTriangulator::ConstraintDelaunayTriangulator(float area) - : fMaxArea(area) + : fMaxArea(area) { // silent warning: -Wunused-private-field (void)fMaxArea; @@ -733,9 +806,9 @@ bool ConstraintDelaunayTriangulator::Triangulate() // sort the points ascending x,y coordinates std::sort(tmp.begin(), tmp.end(), Triangulation::Vertex2d_Less()); // if there are two adjacent points whose distance is less then an epsilon - if (std::adjacent_find(tmp.begin(), tmp.end(), - Triangulation::Vertex2d_EqualTo()) < tmp.end() ) + if (std::adjacent_find(tmp.begin(), tmp.end(), Triangulation::Vertex2d_EqualTo()) < tmp.end()) { return false; + } _facets.clear(); _triangles.clear(); diff --git a/src/Mod/Mesh/App/Core/Triangulation.h b/src/Mod/Mesh/App/Core/Triangulation.h index ef0ff4b9a0..fefbad3f36 100644 --- a/src/Mod/Mesh/App/Core/Triangulation.h +++ b/src/Mod/Mesh/App/Core/Triangulation.h @@ -39,19 +39,17 @@ public: const Base::Vector3f& p1, const Base::Vector3f& p2, const Base::Vector3f& p3) const; - virtual bool MustFlip(const Base::Vector3f& n1, - const Base::Vector3f& n2) const; + virtual bool MustFlip(const Base::Vector3f& n1, const Base::Vector3f& n2) const; }; -class MeshExport TriangulationVerifierV2 : public TriangulationVerifier +class MeshExport TriangulationVerifierV2: public TriangulationVerifier { public: bool Accept(const Base::Vector3f& n, - const Base::Vector3f& p1, - const Base::Vector3f& p2, - const Base::Vector3f& p3) const override; - bool MustFlip(const Base::Vector3f& n1, - const Base::Vector3f& n2) const override; + const Base::Vector3f& p1, + const Base::Vector3f& p2, + const Base::Vector3f& p3) const override; + bool MustFlip(const Base::Vector3f& n1, const Base::Vector3f& n2) const override; }; class MeshExport AbstractPolygonTriangulator @@ -62,7 +60,10 @@ public: /** Sets the polygon to be triangulated. */ void SetPolygon(const std::vector& raclPoints); - void SetIndices(const std::vector& d) {_indices = d;} + void SetIndices(const std::vector& d) + { + _indices = d; + } /** Set a verifier object that checks if the generated triangulation * can be accepted and added to the mesh kernel. * The triangulator takes ownership of the passed verifier. @@ -76,7 +77,10 @@ public: * of the mesh and thus do not need to be touched afterwards. In this * case the method should be reimplemented to return false. */ - virtual bool NeedsReindexing() const { return true; } + virtual bool NeedsReindexing() const + { + return true; + } /** Get the polygon points to be triangulated. The points may be * projected onto its average plane. */ @@ -105,9 +109,15 @@ public: */ virtual void PostProcessing(const std::vector&); /** Returns the geometric triangles of the polygon. */ - const std::vector& GetTriangles() const { return _triangles;} + const std::vector& GetTriangles() const + { + return _triangles; + } /** Returns the topologic facets of the polygon. */ - const std::vector& GetFacets() const { return _facets;} + const std::vector& GetFacets() const + { + return _facets; + } /** Returns the triangle to a given topologic facet. */ virtual MeshGeomFacet GetTriangle(const MeshPointArray&, const MeshFacet&) const; /** Returns the length of the polygon */ @@ -129,22 +139,22 @@ protected: void Done(); protected: - bool _discard; - Base::Matrix4D _inverse; - std::vector _indices; + bool _discard; + Base::Matrix4D _inverse; + std::vector _indices; std::vector _points; std::vector _newpoints; - std::vector _triangles; - std::vector _facets; - std::vector _info; - TriangulationVerifier* _verifier; + std::vector _triangles; + std::vector _facets; + std::vector _info; + TriangulationVerifier* _verifier; }; /** * The EarClippingTriangulator embeds an efficient algorithm to triangulate * polygons taken from http://www.flipcode.com/files/code/triangulate.cpp. */ -class MeshExport EarClippingTriangulator : public AbstractPolygonTriangulator +class MeshExport EarClippingTriangulator: public AbstractPolygonTriangulator { public: EarClippingTriangulator(); @@ -154,38 +164,45 @@ protected: private: /** - * Static class to triangulate any contour/polygon (without holes) efficiently. - * The original code snippet was submitted to FlipCode.com by John W. Ratcliff - * (jratcliff@verant.com) on July 22, 2000. - * The original vector of 2d points is replaced by a vector of 3d points where the - * z-coordinate is ignored. This is because the algorithm is often used for 3d points - * projected to a common plane. The result vector of 2d points is replaced by an - * array of indices to the points of the polygon. - */ + * Static class to triangulate any contour/polygon (without holes) efficiently. + * The original code snippet was submitted to FlipCode.com by John W. Ratcliff + * (jratcliff@verant.com) on July 22, 2000. + * The original vector of 2d points is replaced by a vector of 3d points where the + * z-coordinate is ignored. This is because the algorithm is often used for 3d points + * projected to a common plane. The result vector of 2d points is replaced by an + * array of indices to the points of the polygon. + */ class Triangulate { public: // triangulate a contour/polygon, places results in STL vector // as series of triangles.indicating the points - static bool Process(const std::vector &contour, - std::vector &result); + static bool Process(const std::vector& contour, + std::vector& result); // compute area of a contour/polygon - static float Area(const std::vector &contour); + static float Area(const std::vector& contour); // decide if point Px/Py is inside triangle defined by // (Ax,Ay) (Bx,By) (Cx,Cy) - static bool InsideTriangle(float Ax, float Ay, float Bx, float By, - float Cx, float Cy, float Px, float Py); + static bool InsideTriangle(float Ax, + float Ay, + float Bx, + float By, + float Cx, + float Cy, + float Px, + float Py); static bool _invert; + private: - static bool Snip(const std::vector &contour, - int u,int v,int w,int n,int *V); + static bool + Snip(const std::vector& contour, int u, int v, int w, int n, int* V); }; }; -class MeshExport QuasiDelaunayTriangulator : public EarClippingTriangulator +class MeshExport QuasiDelaunayTriangulator: public EarClippingTriangulator { public: QuasiDelaunayTriangulator(); @@ -194,7 +211,7 @@ protected: bool Triangulate() override; }; -class MeshExport DelaunayTriangulator : public AbstractPolygonTriangulator +class MeshExport DelaunayTriangulator: public AbstractPolygonTriangulator { public: DelaunayTriangulator(); @@ -203,7 +220,7 @@ protected: bool Triangulate() override; }; -class MeshExport FlatTriangulator : public AbstractPolygonTriangulator +class MeshExport FlatTriangulator: public AbstractPolygonTriangulator { public: FlatTriangulator(); @@ -214,7 +231,7 @@ protected: bool Triangulate() override; }; -class MeshExport ConstraintDelaunayTriangulator : public AbstractPolygonTriangulator +class MeshExport ConstraintDelaunayTriangulator: public AbstractPolygonTriangulator { public: explicit ConstraintDelaunayTriangulator(float area); @@ -246,7 +263,7 @@ protected: }; #endif -} // namespace MeshCore +} // namespace MeshCore #endif // MESH_TRIANGULATION_H diff --git a/src/Mod/Mesh/App/Core/Trim.cpp b/src/Mod/Mesh/App/Core/Trim.cpp index 5359c591b3..00c1b58a4f 100644 --- a/src/Mod/Mesh/App/Core/Trim.cpp +++ b/src/Mod/Mesh/App/Core/Trim.cpp @@ -22,38 +22,40 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include -#include "Trim.h" #include "Grid.h" #include "Iterator.h" +#include "Trim.h" using namespace MeshCore; -MeshTrimming::MeshTrimming(MeshKernel &rclM, const Base::ViewProjMethod* pclProj, +MeshTrimming::MeshTrimming(MeshKernel& rclM, + const Base::ViewProjMethod* pclProj, const Base::Polygon2d& rclPoly) - : myMesh(rclM), myProj(pclProj), myPoly(rclPoly) -{ -} + : myMesh(rclM) + , myProj(pclProj) + , myPoly(rclPoly) +{} void MeshTrimming::SetInnerOrOuter(TMode tMode) { - switch (tMode) - { - case INNER: - myInner = true; - break; - case OUTER: - myInner = false; - break; + switch (tMode) { + case INNER: + myInner = true; + break; + case OUTER: + myInner = false; + break; } } -void MeshTrimming::CheckFacets(const MeshFacetGrid& rclGrid, std::vector &raulFacets) const +void MeshTrimming::CheckFacets(const MeshFacetGrid& rclGrid, + std::vector& raulFacets) const { std::vector::iterator it; MeshFacetIterator clIter(myMesh, 0); @@ -79,14 +81,16 @@ void MeshTrimming::CheckFacets(const MeshFacetGrid& rclGrid, std::vectoroperator ()(pnt); - if (myPoly.Contains(Base::Vector2d(clPt2d.x, clPt2d.y)) == myInner) + Base::Vector3f clPt2d = myProj->operator()(pnt); + if (myPoly.Contains(Base::Vector2d(clPt2d.x, clPt2d.y)) == myInner) { return true; - else + } + else { clPoly.Add(Base::Vector2d(clPt2d.x, clPt2d.y)); + } } // is corner of polygon inside the facet - for (size_t j=0; j(A.x*B.y+A.y*C.x+B.x*C.y-(B.y*C.x+A.y*B.x+A.x*C.y)); + fDetABC = + static_cast(A.x * B.y + A.y * C.x + B.x * C.y - (B.y * C.x + A.y * B.x + A.x * C.y)); - for (size_t j=0; j calculate the corresponding 3d-point if (clFacPoly.Contains(myPoly[j])) { P = myPoly[j]; - fDetPAC = static_cast(A.x*P.y+A.y*C.x+P.x*C.y-(P.y*C.x+A.y*P.x+A.x*C.y)); - fDetPBC = static_cast(P.x*B.y+P.y*C.x+B.x*C.y-(B.y*C.x+P.y*B.x+P.x*C.y)); - fDetPAB = static_cast(A.x*B.y+A.y*P.x+B.x*P.y-(B.y*P.x+A.y*B.x+A.x*P.y)); + fDetPAC = static_cast(A.x * P.y + A.y * C.x + P.x * C.y + - (P.y * C.x + A.y * P.x + A.x * C.y)); + fDetPBC = static_cast(P.x * B.y + P.y * C.x + B.x * C.y + - (B.y * C.x + P.y * B.x + P.x * C.y)); + fDetPAB = static_cast(A.x * B.y + A.y * P.x + B.x * P.y + - (B.y * P.x + A.y * B.x + A.x * P.y)); u = fDetPBC / fDetABC; v = fDetPAC / fDetABC; w = fDetPAB / fDetABC; // point is on edge or no valid convex combination - if (u == 0.0f || v == 0.0f || w == 0.0f || fabs(u+v+w-1.0f) >= 0.001f) + if (u == 0.0f || v == 0.0f || w == 0.0f || fabs(u + v + w - 1.0f) >= 0.001f) { return false; + } // 3d point - clPoint = u*rclFacet._aclPoints[0]+v*rclFacet._aclPoints[1]+w*rclFacet._aclPoints[2]; + clPoint = u * rclFacet._aclPoints[0] + v * rclFacet._aclPoints[1] + + w * rclFacet._aclPoints[2]; return true; } @@ -193,29 +209,33 @@ bool MeshTrimming::IsPolygonPointInFacet(FacetIndex ulIndex, Base::Vector3f& clP return false; } -bool MeshTrimming::GetIntersectionPointsOfPolygonAndFacet(FacetIndex ulIndex, int& iSide, std::vector& raclPoints) const +bool MeshTrimming::GetIntersectionPointsOfPolygonAndFacet( + FacetIndex ulIndex, + int& iSide, + std::vector& raclPoints) const { MeshGeomFacet clFac(myMesh.GetFacet(ulIndex)); Base::Vector2d S; Base::Line2d clFacLine, clPolyLine; - int iIntersections=0; - int iIntsctWithEdge0=0, iIntsctWithEdge1=0, iIntsctWithEdge2=0; + int iIntersections = 0; + int iIntsctWithEdge0 = 0, iIntsctWithEdge1 = 0, iIntsctWithEdge2 = 0; // Edge with no intersection iSide = -1; - for (size_t i=0; i((P2-P1).Length()); - float fSP1 = static_cast((P1-S).Length()); - float fSP2 = static_cast((P2-S).Length()); + bool bPushBack = true; + float fP1P2 = static_cast((P2 - P1).Length()); + float fSP1 = static_cast((P1 - S).Length()); + float fSP2 = static_cast((P2 - S).Length()); - float fP3P4 = static_cast((P4-P3).Length()); - float fSP3 = static_cast((P3-S).Length()); - float fSP4 = static_cast((P4-S).Length()); + float fP3P4 = static_cast((P4 - P3).Length()); + float fSP3 = static_cast((P3 - S).Length()); + float fSP4 = static_cast((P4 - S).Length()); // compute proportion of length float l = fSP1 / fP1P2; float m = fSP2 / fP1P2; @@ -246,62 +266,79 @@ bool MeshTrimming::GetIntersectionPointsOfPolygonAndFacet(FacetIndex ulIndex, in float s = fSP4 / fP3P4; // is intersection point convex combination? - if ((fabs(l+m-1.0f) < 0.001f) && (fabs(r+s-1.0f) < 0.001f)) { - Base::Vector3f clIntersection(m*clFac._aclPoints[j]+l*clFac._aclPoints[(j+1)%3]); + if ((fabs(l + m - 1.0f) < 0.001f) && (fabs(r + s - 1.0f) < 0.001f)) { + Base::Vector3f clIntersection(m * clFac._aclPoints[j] + + l * clFac._aclPoints[(j + 1) % 3]); iIntersections++; // only two intersections points per edge allowed if (j == 0) { - if (iIntsctWithEdge0 == 2) + if (iIntsctWithEdge0 == 2) { bPushBack = false; - else + } + else { iIntsctWithEdge0++; + } } else if (j == 1) { - if (iIntsctWithEdge1 == 2) + if (iIntsctWithEdge1 == 2) { bPushBack = false; - else + } + else { iIntsctWithEdge1++; + } } else { - if (iIntsctWithEdge2 == 2) + if (iIntsctWithEdge2 == 2) { bPushBack = false; - else + } + else { iIntsctWithEdge2++; + } } - if (bPushBack) + if (bPushBack) { raclPoints.push_back(clIntersection); + } } } } } // check for rotating facet later - if (iIntsctWithEdge0 == 0) + if (iIntsctWithEdge0 == 0) { iSide = 0; - else if (iIntsctWithEdge1 == 0) + } + else if (iIntsctWithEdge1 == 0) { iSide = 1; - else if (iIntsctWithEdge2 == 0) + } + else if (iIntsctWithEdge2 == 0) { iSide = 2; + } // further check (for rotating the facet) - if (iIntsctWithEdge0 == 0 && iIntsctWithEdge1 == 0) + if (iIntsctWithEdge0 == 0 && iIntsctWithEdge1 == 0) { iSide = 1; - else if (iIntsctWithEdge0 == 0 && iIntsctWithEdge2 == 0) + } + else if (iIntsctWithEdge0 == 0 && iIntsctWithEdge2 == 0) { iSide = 0; - else if (iIntsctWithEdge1 == 0 && iIntsctWithEdge2 == 0) + } + else if (iIntsctWithEdge1 == 0 && iIntsctWithEdge2 == 0) { iSide = 2; + } // and last another check if (iIntsctWithEdge0 * iIntsctWithEdge1 * iIntsctWithEdge2 > 0) { - if (iIntsctWithEdge0 == 2) + if (iIntsctWithEdge0 == 2) { iSide = 2; - else if (iIntsctWithEdge1 == 2) + } + else if (iIntsctWithEdge1 == 2) { iSide = 0; - else if (iIntsctWithEdge2 == 2) + } + else if (iIntsctWithEdge2 == 2) { iSide = 1; + } } return iIntersections > 0; @@ -333,33 +370,40 @@ void MeshTrimming::AdjustFacet(MeshFacet& facet, int iInd) } } -bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vector& raclPoints, std::vector& aclNewFacets) +bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, + int iSide, + const std::vector& raclPoints, + std::vector& aclNewFacets) { MeshGeomFacet clFac; // no valid triangulation possible - if (iSide == -1) + if (iSide == -1) { return false; + } // no intersection point found => triangle is only touched at a corner point if (raclPoints.empty()) { MeshFacet& facet = myMesh._aclFacetArray[ulFacetPos]; - int iCtPtsIn=0; - int iCtPtsOn=0; + int iCtPtsIn = 0; + int iCtPtsOn = 0; Base::Vector3f clFacPnt; Base::Vector2d clProjPnt; for (PointIndex ptIndex : facet._aulPoints) { clFacPnt = (*myProj)(myMesh._aclPointArray[ptIndex]); clProjPnt = Base::Vector2d(clFacPnt.x, clFacPnt.y); - if (myPoly.Intersect(clProjPnt, double(MESH_MIN_PT_DIST))) + if (myPoly.Intersect(clProjPnt, double(MESH_MIN_PT_DIST))) { ++iCtPtsOn; - else if (myPoly.Contains(clProjPnt) == myInner) + } + else if (myPoly.Contains(clProjPnt) == myInner) { ++iCtPtsIn; + } } // in this case we can use the original triangle - if (iCtPtsIn != (3 - iCtPtsOn)) + if (iCtPtsIn != (3 - iCtPtsOn)) { aclNewFacets.push_back(myMesh.GetFacet(ulFacetPos)); + } } // one intersection point found => triangle is also touched at a corner point else if (raclPoints.size() == 1) { @@ -370,9 +414,9 @@ bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vec // determine the edge containing the intersection point Base::Line2d clFacLine; - for (int j=0; j<3; j++) { + for (int j = 0; j < 3; j++) { Base::Vector3f clP1((*myProj)(clFac._aclPoints[j])); - Base::Vector3f clP2((*myProj)(clFac._aclPoints[(j+1)%3])); + Base::Vector3f clP2((*myProj)(clFac._aclPoints[(j + 1) % 3])); Base::Vector2d P1(clP1.x, clP1.y); Base::Vector2d P2(clP2.x, clP2.y); clFacLine.clV1 = P1; @@ -382,15 +426,15 @@ bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vec if (myPoly.Contains(P1) == myInner) { MeshGeomFacet clNew; clNew._aclPoints[0] = raclPoints[0]; - clNew._aclPoints[1] = clFac._aclPoints[(j+1)%3]; - clNew._aclPoints[2] = clFac._aclPoints[(j+2)%3]; + clNew._aclPoints[1] = clFac._aclPoints[(j + 1) % 3]; + clNew._aclPoints[2] = clFac._aclPoints[(j + 2) % 3]; aclNewFacets.push_back(clNew); break; } else if (myPoly.Contains(P2) == myInner) { MeshGeomFacet clNew; clNew._aclPoints[0] = raclPoints[0]; - clNew._aclPoints[1] = clFac._aclPoints[(j+2)%3]; + clNew._aclPoints[1] = clFac._aclPoints[(j + 2) % 3]; clNew._aclPoints[2] = clFac._aclPoints[j]; aclNewFacets.push_back(clNew); break; @@ -411,14 +455,15 @@ bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vec } // check which facets can be inserted - int iCtPts=0; + int iCtPts = 0; Base::Vector3f clFacPnt; Base::Vector2d clProjPnt; for (PointIndex ptIndex : facet._aulPoints) { clFacPnt = (*myProj)(myMesh._aclPointArray[ptIndex]); clProjPnt = Base::Vector2d(clFacPnt.x, clFacPnt.y); - if (myPoly.Contains(clProjPnt) == myInner) + if (myPoly.Contains(clProjPnt) == myInner) { ++iCtPts; + } } if (iCtPts == 2) { @@ -440,8 +485,9 @@ bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vec clFac._aclPoints[2] = clP2; aclNewFacets.push_back(clFac); } - else + else { return false; + } } // four intersection points found else if (raclPoints.size() == 4) { @@ -450,17 +496,19 @@ bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vec clFac = myMesh.GetFacet(ulFacetPos); // intersection points - Base::Vector3f clP1(raclPoints[0]), clP2(raclPoints[1]), clP3(raclPoints[2]), clP4(raclPoints[3]); + Base::Vector3f clP1(raclPoints[0]), clP2(raclPoints[1]), clP3(raclPoints[2]), + clP4(raclPoints[3]); // check which facets can be inserted - int iCtPts=0; + int iCtPts = 0; Base::Vector3f clFacPnt; Base::Vector2d clProjPnt; for (PointIndex ptIndex : facet._aulPoints) { clFacPnt = (*myProj)(myMesh._aclPointArray[ptIndex]); clProjPnt = Base::Vector2d(clFacPnt.x, clFacPnt.y); - if (myPoly.Contains(clProjPnt) == myInner) + if (myPoly.Contains(clProjPnt) == myInner) { ++iCtPts; + } } // sort the intersection points in a certain order @@ -473,13 +521,13 @@ bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vec clP4 = raclPoints[2]; } - if ((clP1-clFac._aclPoints[1]).Length() > (clP3-clFac._aclPoints[1]).Length()) { + if ((clP1 - clFac._aclPoints[1]).Length() > (clP3 - clFac._aclPoints[1]).Length()) { // swap P1 and P3 Base::Vector3f tmp(clP1); clP1 = clP3; clP3 = tmp; } - if ((clP2-clFac._aclPoints[0]).Length() > (clP4-clFac._aclPoints[0]).Length()) { + if ((clP2 - clFac._aclPoints[0]).Length() > (clP4 - clFac._aclPoints[0]).Length()) { // swap P2 and P4 Base::Vector3f tmp(clP2); clP2 = clP4; @@ -489,8 +537,10 @@ bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vec else { if (iSide == 0) { Base::Vector3f clNormal(clFac.GetNormal()); - MeshGeomFacet clTmpFac; clTmpFac._aclPoints[0] = clFac._aclPoints[1]; - clTmpFac._aclPoints[1] = clP2; clTmpFac._aclPoints[2] = clP1; + MeshGeomFacet clTmpFac; + clTmpFac._aclPoints[0] = clFac._aclPoints[1]; + clTmpFac._aclPoints[1] = clP2; + clTmpFac._aclPoints[2] = clP1; if (clTmpFac.GetNormal() * clNormal > 0) { Base::Vector3f tmp(clP1); clP1 = clP2; @@ -505,7 +555,7 @@ bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vec } } else if (iSide == 1) { - if ((clP2-clFac._aclPoints[1]).Length() > (clP4-clFac._aclPoints[1]).Length()) { + if ((clP2 - clFac._aclPoints[1]).Length() > (clP4 - clFac._aclPoints[1]).Length()) { Base::Vector3f tmp(clP1); clP1 = clP4; clP4 = tmp; @@ -523,7 +573,7 @@ bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vec } } else { - if ((clP1-clFac._aclPoints[1]).Length() > (clP3-clFac._aclPoints[1]).Length()) { + if ((clP1 - clFac._aclPoints[1]).Length() > (clP3 - clFac._aclPoints[1]).Length()) { Base::Vector3f tmp(clP1); clP1 = clP3; clP3 = tmp; @@ -594,18 +644,23 @@ bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vec aclNewFacets.push_back(clFac); } } - else + else { return false; + } return true; } -bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vector& raclPoints, Base::Vector3f& clP3, +bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, + int iSide, + const std::vector& raclPoints, + Base::Vector3f& clP3, std::vector& aclNewFacets) { // no valid triangulation possible - if (iSide == -1 || raclPoints.size() < 2) + if (iSide == -1 || raclPoints.size() < 2) { return false; + } Base::Vector3f clP1(raclPoints[0]); Base::Vector3f clP2(raclPoints[1]); @@ -615,12 +670,12 @@ bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vec MeshGeomFacet clFac; - float fDistEdgeP1 = clP1.DistanceToLineSegment( - myMesh._aclPointArray[facet._aulPoints[1]], - myMesh._aclPointArray[facet._aulPoints[2]]).Length(); - float fDistEdgeP2 = clP2.DistanceToLineSegment( - myMesh._aclPointArray[facet._aulPoints[1]], - myMesh._aclPointArray[facet._aulPoints[2]]).Length(); + float fDistEdgeP1 = clP1.DistanceToLineSegment(myMesh._aclPointArray[facet._aulPoints[1]], + myMesh._aclPointArray[facet._aulPoints[2]]) + .Length(); + float fDistEdgeP2 = clP2.DistanceToLineSegment(myMesh._aclPointArray[facet._aulPoints[1]], + myMesh._aclPointArray[facet._aulPoints[2]]) + .Length(); // swap P1 and P2 if (fDistEdgeP2 < fDistEdgeP1) { @@ -630,18 +685,19 @@ bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vec } // check which facets should be inserted - int iCtPts=0; + int iCtPts = 0; Base::Vector3f clFacPnt; Base::Vector2d clProjPnt; for (PointIndex ptIndex : facet._aulPoints) { clFacPnt = (*myProj)(myMesh._aclPointArray[ptIndex]); clProjPnt = Base::Vector2d(clFacPnt.x, clFacPnt.y); - if (myPoly.Contains(clProjPnt) == myInner) + if (myPoly.Contains(clProjPnt) == myInner) { ++iCtPts; + } } if (iCtPts == 3) { clFac = myMesh.GetFacet(ulFacetPos); - if ((clP1-clFac._aclPoints[1]).Length() > (clP2-clFac._aclPoints[1]).Length()) { + if ((clP1 - clFac._aclPoints[1]).Length() > (clP2 - clFac._aclPoints[1]).Length()) { Base::Vector3f tmp(clP1); clP1 = clP2; clP2 = tmp; @@ -683,7 +739,7 @@ bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vec } else if (iCtPts == 0) { clFac = myMesh.GetFacet(ulFacetPos); - if ((clP1-clFac._aclPoints[1]).Length() > (clP2-clFac._aclPoints[1]).Length()) { + if ((clP1 - clFac._aclPoints[1]).Length() > (clP2 - clFac._aclPoints[1]).Length()) { Base::Vector3f tmp(clP1); clP1 = clP2; clP2 = tmp; @@ -713,7 +769,8 @@ bool MeshTrimming::CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vec return true; } -void MeshTrimming::TrimFacets(const std::vector& raulFacets, std::vector& aclNewFacets) +void MeshTrimming::TrimFacets(const std::vector& raulFacets, + std::vector& aclNewFacets) { Base::Vector3f clP; std::vector clIntsct; @@ -726,15 +783,17 @@ void MeshTrimming::TrimFacets(const std::vector& raulFacets, std::ve // facet must be trimmed if (!PolygonContainsCompleteFacet(myInner, index)) { // generate new facets - if (GetIntersectionPointsOfPolygonAndFacet(index, iSide, clIntsct)) + if (GetIntersectionPointsOfPolygonAndFacet(index, iSide, clIntsct)) { CreateFacets(index, iSide, clIntsct, myTriangles); + } } } // facet contains a polygon point else { // generate new facets - if (GetIntersectionPointsOfPolygonAndFacet(index, iSide, clIntsct)) + if (GetIntersectionPointsOfPolygonAndFacet(index, iSide, clIntsct)) { CreateFacets(index, iSide, clIntsct, clP, myTriangles); + } } seq.next(); } diff --git a/src/Mod/Mesh/App/Core/Trim.h b/src/Mod/Mesh/App/Core/Trim.h index 5360567a21..8ced23c795 100644 --- a/src/Mod/Mesh/App/Core/Trim.h +++ b/src/Mod/Mesh/App/Core/Trim.h @@ -28,7 +28,8 @@ #include "MeshKernel.h" -namespace MeshCore { +namespace MeshCore +{ /** * Checks the facets in 2D and then trim them in 3D @@ -36,21 +37,30 @@ namespace MeshCore { class MeshExport MeshTrimming { public: - enum TMode {INNER, OUTER}; + enum TMode + { + INNER, + OUTER + }; public: - MeshTrimming(MeshKernel& mesh, const Base::ViewProjMethod* pclProj, const Base::Polygon2d& rclPoly); + MeshTrimming(MeshKernel& mesh, + const Base::ViewProjMethod* pclProj, + const Base::Polygon2d& rclPoly); public: /** - * Checks all facets for intersection with the polygon and writes all touched facets into the vector + * Checks all facets for intersection with the polygon and writes all touched facets into the + * vector */ void CheckFacets(const MeshFacetGrid& rclGrid, std::vector& raulFacets) const; /** - * The facets from raulFacets will be trimmed or deleted and aclNewFacets gives the new generated facets + * The facets from raulFacets will be trimmed or deleted and aclNewFacets gives the new + * generated facets */ - void TrimFacets(const std::vector& raulFacets, std::vector& aclNewFacets); + void TrimFacets(const std::vector& raulFacets, + std::vector& aclNewFacets); /** * Setter: Trimm INNER or OUTER @@ -71,14 +81,19 @@ private: /** * Creates new facets from edge points of the facet */ - bool CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vector& raclPoints, - std::vector& aclNewFacets); + bool CreateFacets(FacetIndex ulFacetPos, + int iSide, + const std::vector& raclPoints, + std::vector& aclNewFacets); /** * Creates new facets from edge points of the facet and a point inside the facet */ - bool CreateFacets(FacetIndex ulFacetPos, int iSide, const std::vector& raclPoints, - Base::Vector3f& clP3, std::vector& aclNewFacets); + bool CreateFacets(FacetIndex ulFacetPos, + int iSide, + const std::vector& raclPoints, + Base::Vector3f& clP3, + std::vector& aclNewFacets); /** * Checks if a polygon point lies within a facet @@ -89,19 +104,20 @@ private: * Calculates the two intersection points between polygonline and facet in 2D * and project the points back into 3D (not very exactly) */ - bool GetIntersectionPointsOfPolygonAndFacet(FacetIndex ulIndex, int& iSide, - std::vector& raclPoints) const; + bool GetIntersectionPointsOfPolygonAndFacet(FacetIndex ulIndex, + int& iSide, + std::vector& raclPoints) const; void AdjustFacet(MeshFacet& facet, int iInd); private: MeshKernel& myMesh; - bool myInner{true}; + bool myInner {true}; std::vector myTriangles; const Base::ViewProjMethod* myProj; const Base::Polygon2d& myPoly; }; -} //namespace MeshCore +} // namespace MeshCore -#endif //MESHTRIM_H +#endif // MESHTRIM_H diff --git a/src/Mod/Mesh/App/Core/TrimByPlane.cpp b/src/Mod/Mesh/App/Core/TrimByPlane.cpp index f69504a6b4..0930725fdf 100644 --- a/src/Mod/Mesh/App/Core/TrimByPlane.cpp +++ b/src/Mod/Mesh/App/Core/TrimByPlane.cpp @@ -22,23 +22,25 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif -#include "TrimByPlane.h" #include "Grid.h" #include "Iterator.h" +#include "TrimByPlane.h" using namespace MeshCore; -MeshTrimByPlane::MeshTrimByPlane(MeshKernel &rclM) - : myMesh(rclM) -{ -} +MeshTrimByPlane::MeshTrimByPlane(MeshKernel& rclM) + : myMesh(rclM) +{} -void MeshTrimByPlane::CheckFacets(const MeshFacetGrid& rclGrid, const Base::Vector3f& base, const Base::Vector3f& normal, - std::vector &trimFacets, std::vector& removeFacets) const +void MeshTrimByPlane::CheckFacets(const MeshFacetGrid& rclGrid, + const Base::Vector3f& base, + const Base::Vector3f& normal, + std::vector& trimFacets, + std::vector& removeFacets) const { // Go through the grid and check for each cell if its bounding box intersects the plane. // If the box is completely below the plane all facets will be kept, if it's above the @@ -59,9 +61,10 @@ void MeshTrimByPlane::CheckFacets(const MeshFacetGrid& rclGrid, const Base::Vect // remove double elements std::sort(checkElements.begin(), checkElements.end()); - checkElements.erase(std::unique(checkElements.begin(), checkElements.end()), checkElements.end()); + checkElements.erase(std::unique(checkElements.begin(), checkElements.end()), + checkElements.end()); - trimFacets.reserve(checkElements.size()/2); // reserve some memory + trimFacets.reserve(checkElements.size() / 2); // reserve some memory for (FacetIndex element : checkElements) { MeshGeomFacet clFacet = myMesh.GetFacet(element); if (clFacet.IntersectWithPlane(base, normal)) { @@ -78,8 +81,11 @@ void MeshTrimByPlane::CheckFacets(const MeshFacetGrid& rclGrid, const Base::Vect removeFacets.erase(std::unique(removeFacets.begin(), removeFacets.end()), removeFacets.end()); } -void MeshTrimByPlane::CreateOneFacet(const Base::Vector3f& base, const Base::Vector3f& normal, unsigned short shift, - const MeshGeomFacet& facet, std::vector& trimmedFacets) const +void MeshTrimByPlane::CreateOneFacet(const Base::Vector3f& base, + const Base::Vector3f& normal, + unsigned short shift, + const MeshGeomFacet& facet, + std::vector& trimmedFacets) const { unsigned short nul = shift % 3; unsigned short one = (shift + 1) % 3; @@ -103,8 +109,11 @@ void MeshTrimByPlane::CreateOneFacet(const Base::Vector3f& base, const Base::Vec trimmedFacets.push_back(create); } -void MeshTrimByPlane::CreateTwoFacet(const Base::Vector3f& base, const Base::Vector3f& normal, unsigned short shift, - const MeshGeomFacet& facet, std::vector& trimmedFacets) const +void MeshTrimByPlane::CreateTwoFacet(const Base::Vector3f& base, + const Base::Vector3f& normal, + unsigned short shift, + const MeshGeomFacet& facet, + std::vector& trimmedFacets) const { unsigned short nul = shift % 3; unsigned short one = (shift + 1) % 3; @@ -133,8 +142,10 @@ void MeshTrimByPlane::CreateTwoFacet(const Base::Vector3f& base, const Base::Vec trimmedFacets.push_back(create); } -void MeshTrimByPlane::TrimFacets(const std::vector& trimFacets, const Base::Vector3f& base, - const Base::Vector3f& normal, std::vector& trimmedFacets) +void MeshTrimByPlane::TrimFacets(const std::vector& trimFacets, + const Base::Vector3f& base, + const Base::Vector3f& normal, + std::vector& trimmedFacets) { trimmedFacets.reserve(2 * trimFacets.size()); for (FacetIndex index : trimFacets) { diff --git a/src/Mod/Mesh/App/Core/TrimByPlane.h b/src/Mod/Mesh/App/Core/TrimByPlane.h index 65883fa7c7..d0ccc9d309 100644 --- a/src/Mod/Mesh/App/Core/TrimByPlane.h +++ b/src/Mod/Mesh/App/Core/TrimByPlane.h @@ -26,7 +26,8 @@ #include "MeshKernel.h" -namespace MeshCore { +namespace MeshCore +{ /** * Trim the facets in 3D with a plane @@ -39,27 +40,40 @@ public: public: /** - * Checks all facets for intersection with the plane and writes all touched facets into the vector + * Checks all facets for intersection with the plane and writes all touched facets into the + * vector */ - void CheckFacets(const MeshFacetGrid& rclGrid, const Base::Vector3f& base, const Base::Vector3f& normal, - std::vector& trimFacets, std::vector& removeFacets) const; + void CheckFacets(const MeshFacetGrid& rclGrid, + const Base::Vector3f& base, + const Base::Vector3f& normal, + std::vector& trimFacets, + std::vector& removeFacets) const; /** - * The facets from \a trimFacets will be trimmed or deleted and \a trimmedFacets holds the newly generated facets + * The facets from \a trimFacets will be trimmed or deleted and \a trimmedFacets holds the newly + * generated facets */ - void TrimFacets(const std::vector& trimFacets, const Base::Vector3f& base, - const Base::Vector3f& normal, std::vector& trimmedFacets); + void TrimFacets(const std::vector& trimFacets, + const Base::Vector3f& base, + const Base::Vector3f& normal, + std::vector& trimmedFacets); private: - void CreateOneFacet(const Base::Vector3f& base, const Base::Vector3f& normal, unsigned short shift, - const MeshGeomFacet& facet, std::vector& trimmedFacets) const; - void CreateTwoFacet(const Base::Vector3f& base, const Base::Vector3f& normal, unsigned short shift, - const MeshGeomFacet& facet, std::vector& trimmedFacets) const; + void CreateOneFacet(const Base::Vector3f& base, + const Base::Vector3f& normal, + unsigned short shift, + const MeshGeomFacet& facet, + std::vector& trimmedFacets) const; + void CreateTwoFacet(const Base::Vector3f& base, + const Base::Vector3f& normal, + unsigned short shift, + const MeshGeomFacet& facet, + std::vector& trimmedFacets) const; private: MeshKernel& myMesh; }; -} //namespace MeshCore +} // namespace MeshCore -#endif //MESHTRIM_BY_PLANE_H +#endif // MESHTRIM_BY_PLANE_H diff --git a/src/Mod/Mesh/App/Core/Utilities.h b/src/Mod/Mesh/App/Core/Utilities.h index 305e7c0b41..bb177836d9 100644 --- a/src/Mod/Mesh/App/Core/Utilities.h +++ b/src/Mod/Mesh/App/Core/Utilities.h @@ -27,32 +27,43 @@ #include -namespace Base { +namespace Base +{ // Specialization for Wm4::Vector3d -template <> -struct vec_traits { +template<> +struct vec_traits +{ using vec_type = Wm4::Vector3d; using float_type = double; - explicit vec_traits(const vec_type& v) : v(v){} - inline std::tuple get() const { + explicit vec_traits(const vec_type& v) + : v(v) + {} + inline std::tuple get() const + { return std::make_tuple(v.X(), v.Y(), v.Z()); } + private: const vec_type& v; }; // Specialization for Wm4::Vector3f -template <> -struct vec_traits { +template<> +struct vec_traits +{ using vec_type = Wm4::Vector3f; using float_type = float; - explicit vec_traits(const vec_type& v) : v(v){} - inline std::tuple get() const { + explicit vec_traits(const vec_type& v) + : v(v) + {} + inline std::tuple get() const + { return std::make_tuple(v.X(), v.Y(), v.Z()); } + private: const vec_type& v; }; -} +} // namespace Base -#endif // MESH_UTILITIES_H +#endif // MESH_UTILITIES_H diff --git a/src/Mod/Mesh/App/Core/Visitor.cpp b/src/Mod/Mesh/App/Core/Visitor.cpp index fce056f419..77927794fd 100644 --- a/src/Mod/Mesh/App/Core/Visitor.cpp +++ b/src/Mod/Mesh/App/Core/Visitor.cpp @@ -22,21 +22,22 @@ #include "PreCompiled.h" -#include "MeshKernel.h" // must be before Visitor.h -#include "Visitor.h" #include "Algorithm.h" #include "Approximation.h" +#include "MeshKernel.h" // must be before Visitor.h +#include "Visitor.h" using namespace MeshCore; -unsigned long MeshKernel::VisitNeighbourFacets (MeshFacetVisitor &rclFVisitor, FacetIndex ulStartFacet) const +unsigned long MeshKernel::VisitNeighbourFacets(MeshFacetVisitor& rclFVisitor, + FacetIndex ulStartFacet) const { unsigned long ulVisited = 0, j, ulLevel = 0; unsigned long ulCount = _aclFacetArray.size(); std::vector clCurrentLevel, clNextLevel; - std::vector::iterator clCurrIter; + std::vector::iterator clCurrIter; MeshFacetArray::_TConstIterator clCurrFacet, clNBFacet; // pick up start point @@ -51,26 +52,31 @@ unsigned long MeshKernel::VisitNeighbourFacets (MeshFacetVisitor &rclFVisitor, F // visit all neighbours of the current level if not yet done for (unsigned short i = 0; i < 3; i++) { - j = clCurrFacet->_aulNeighbours[i]; // index to neighbour facet - if (j == FACET_INDEX_MAX) - continue; // no neighbour facet + j = clCurrFacet->_aulNeighbours[i]; // index to neighbour facet + if (j == FACET_INDEX_MAX) { + continue; // no neighbour facet + } - if (j >= ulCount) - continue; // error in data structure + if (j >= ulCount) { + continue; // error in data structure + } clNBFacet = _aclFacetArray.begin() + j; - if (!rclFVisitor.AllowVisit(*clNBFacet, *clCurrFacet, j, ulLevel, i)) + if (!rclFVisitor.AllowVisit(*clNBFacet, *clCurrFacet, j, ulLevel, i)) { continue; - if (clNBFacet->IsFlag(MeshFacet::VISIT)) - continue; // neighbour facet already visited + } + if (clNBFacet->IsFlag(MeshFacet::VISIT)) { + continue; // neighbour facet already visited + } else { // visit and mark ulVisited++; clNextLevel.push_back(j); clNBFacet->SetFlag(MeshFacet::VISIT); - if (!rclFVisitor.Visit(*clNBFacet, *clCurrFacet, j, ulLevel)) + if (!rclFVisitor.Visit(*clNBFacet, *clCurrFacet, j, ulLevel)) { return ulVisited; + } } } } @@ -83,7 +89,8 @@ unsigned long MeshKernel::VisitNeighbourFacets (MeshFacetVisitor &rclFVisitor, F return ulVisited; } -unsigned long MeshKernel::VisitNeighbourFacetsOverCorners (MeshFacetVisitor &rclFVisitor, FacetIndex ulStartFacet) const +unsigned long MeshKernel::VisitNeighbourFacetsOverCorners(MeshFacetVisitor& rclFVisitor, + FacetIndex ulStartFacet) const { unsigned long ulVisited = 0, ulLevel = 0; MeshRefPointToFacets clRPF(*this); @@ -96,9 +103,11 @@ unsigned long MeshKernel::VisitNeighbourFacetsOverCorners (MeshFacetVisitor &rcl while (!aclCurrentLevel.empty()) { // visit all neighbours of the current level - for (std::vector::iterator pCurrFacet = aclCurrentLevel.begin(); pCurrFacet < aclCurrentLevel.end(); ++pCurrFacet) { + for (std::vector::iterator pCurrFacet = aclCurrentLevel.begin(); + pCurrFacet < aclCurrentLevel.end(); + ++pCurrFacet) { for (int i = 0; i < 3; i++) { - const MeshFacet &rclFacet = raclFAry[*pCurrFacet]; + const MeshFacet& rclFacet = raclFAry[*pCurrFacet]; const std::set& raclNB = clRPF[rclFacet._aulPoints[i]]; for (FacetIndex pINb : raclNB) { if (!pFBegin[pINb].IsFlag(MeshFacet::VISIT)) { @@ -107,8 +116,12 @@ unsigned long MeshKernel::VisitNeighbourFacetsOverCorners (MeshFacetVisitor &rcl FacetIndex ulFInd = pINb; aclNextLevel.push_back(ulFInd); pFBegin[pINb].SetFlag(MeshFacet::VISIT); - if (!rclFVisitor.Visit(pFBegin[pINb], raclFAry[*pCurrFacet], ulFInd, ulLevel)) + if (!rclFVisitor.Visit(pFBegin[pINb], + raclFAry[*pCurrFacet], + ulFInd, + ulLevel)) { return ulVisited; + } } } } @@ -121,11 +134,12 @@ unsigned long MeshKernel::VisitNeighbourFacetsOverCorners (MeshFacetVisitor &rcl return ulVisited; } -unsigned long MeshKernel::VisitNeighbourPoints (MeshPointVisitor &rclPVisitor, PointIndex ulStartPoint) const +unsigned long MeshKernel::VisitNeighbourPoints(MeshPointVisitor& rclPVisitor, + PointIndex ulStartPoint) const { unsigned long ulVisited = 0, ulLevel = 0; std::vector aclCurrentLevel, aclNextLevel; - std::vector::iterator clCurrIter; + std::vector::iterator clCurrIter; MeshPointArray::_TConstIterator pPBegin = _aclPointArray.begin(); MeshRefPointToPoints clNPs(*this); @@ -134,7 +148,8 @@ unsigned long MeshKernel::VisitNeighbourPoints (MeshPointVisitor &rclPVisitor, P while (!aclCurrentLevel.empty()) { // visit all neighbours of the current level - for (clCurrIter = aclCurrentLevel.begin(); clCurrIter < aclCurrentLevel.end(); ++clCurrIter) { + for (clCurrIter = aclCurrentLevel.begin(); clCurrIter < aclCurrentLevel.end(); + ++clCurrIter) { const std::set& raclNB = clNPs[*clCurrIter]; for (PointIndex pINb : raclNB) { if (!pPBegin[pINb].IsFlag(MeshPoint::VISIT)) { @@ -143,8 +158,12 @@ unsigned long MeshKernel::VisitNeighbourPoints (MeshPointVisitor &rclPVisitor, P PointIndex ulPInd = pINb; aclNextLevel.push_back(ulPInd); pPBegin[pINb].SetFlag(MeshPoint::VISIT); - if (!rclPVisitor.Visit(pPBegin[pINb], *(pPBegin + (*clCurrIter)), ulPInd, ulLevel)) + if (!rclPVisitor.Visit(pPBegin[pINb], + *(pPBegin + (*clCurrIter)), + ulPInd, + ulLevel)) { return ulVisited; + } } } } @@ -158,16 +177,15 @@ unsigned long MeshKernel::VisitNeighbourPoints (MeshPointVisitor &rclPVisitor, P // ------------------------------------------------------------------------- -MeshSearchNeighbourFacetsVisitor::MeshSearchNeighbourFacetsVisitor (const MeshKernel &rclMesh, - float fRadius, - FacetIndex ulStartFacetIdx) - : _rclMeshBase(rclMesh), - _clCenter(rclMesh.GetFacet(ulStartFacetIdx).GetGravityPoint()), - _fRadius(fRadius) -{ -} +MeshSearchNeighbourFacetsVisitor::MeshSearchNeighbourFacetsVisitor(const MeshKernel& rclMesh, + float fRadius, + FacetIndex ulStartFacetIdx) + : _rclMeshBase(rclMesh) + , _clCenter(rclMesh.GetFacet(ulStartFacetIdx).GetGravityPoint()) + , _fRadius(fRadius) +{} -std::vector MeshSearchNeighbourFacetsVisitor::GetAndReset () +std::vector MeshSearchNeighbourFacetsVisitor::GetAndReset() { MeshAlgorithm(_rclMeshBase).ResetFacetsFlag(_vecFacets, MeshFacet::VISIT); return _vecFacets; @@ -175,9 +193,14 @@ std::vector MeshSearchNeighbourFacetsVisitor::GetAndReset () // ------------------------------------------------------------------------- -MeshPlaneVisitor::MeshPlaneVisitor (const MeshKernel& mesh, FacetIndex index, - float deviation, std::vector &indices) - : mesh(mesh), indices(indices), max_deviation(deviation), fitter(new PlaneFit) +MeshPlaneVisitor::MeshPlaneVisitor(const MeshKernel& mesh, + FacetIndex index, + float deviation, + std::vector& indices) + : mesh(mesh) + , indices(indices) + , max_deviation(deviation) + , fitter(new PlaneFit) { MeshGeomFacet triangle = mesh.GetFacet(index); basepoint = triangle.GetGravityPoint(); @@ -187,26 +210,33 @@ MeshPlaneVisitor::MeshPlaneVisitor (const MeshKernel& mesh, FacetIndex index, fitter->AddPoint(triangle._aclPoints[2]); } -MeshPlaneVisitor::~MeshPlaneVisitor () +MeshPlaneVisitor::~MeshPlaneVisitor() { delete fitter; } -bool MeshPlaneVisitor::AllowVisit (const MeshFacet& face, const MeshFacet&, - FacetIndex, unsigned long, unsigned short) +bool MeshPlaneVisitor::AllowVisit(const MeshFacet& face, + const MeshFacet&, + FacetIndex, + unsigned long, + unsigned short) { - if (!fitter->Done()) + if (!fitter->Done()) { fitter->Fit(); + } MeshGeomFacet triangle = mesh.GetFacet(face); for (const auto& pnt : triangle._aclPoints) { - if (fabs(fitter->GetDistanceToPlane(pnt)) > max_deviation) + if (fabs(fitter->GetDistanceToPlane(pnt)) > max_deviation) { return false; + } } return true; } -bool MeshPlaneVisitor::Visit (const MeshFacet & face, const MeshFacet &, - FacetIndex ulFInd, unsigned long) +bool MeshPlaneVisitor::Visit(const MeshFacet& face, + const MeshFacet&, + FacetIndex ulFInd, + unsigned long) { MeshGeomFacet triangle = mesh.GetFacet(face); indices.push_back(ulFInd); diff --git a/src/Mod/Mesh/App/Core/Visitor.h b/src/Mod/Mesh/App/Core/Visitor.h index bf991f7799..ce7d89563d 100644 --- a/src/Mod/Mesh/App/Core/Visitor.h +++ b/src/Mod/Mesh/App/Core/Visitor.h @@ -23,11 +23,12 @@ #ifndef VISITOR_H #define VISITOR_H -#include #include "MeshKernel.h" +#include -namespace MeshCore { +namespace MeshCore +{ class MeshFacet; class MeshKernel; @@ -53,15 +54,19 @@ public: * If \a true is returned the next iteration is done if there are still facets to visit. * If \a false is returned the calling method stops immediately visiting further facets. */ - virtual bool Visit (const MeshFacet &rclFacet, const MeshFacet &rclFrom, FacetIndex ulFInd, - unsigned long ulLevel) = 0; + virtual bool Visit(const MeshFacet& rclFacet, + const MeshFacet& rclFrom, + FacetIndex ulFInd, + unsigned long ulLevel) = 0; /** Test before a facet will be flagged as VISIT, return false means: go on with * visiting the facets but not this one and set not the VISIT flag */ - virtual bool AllowVisit (const MeshFacet& rclFacet, const MeshFacet& rclFrom, - FacetIndex ulFInd, unsigned long ulLevel, - unsigned short neighbourIndex) + virtual bool AllowVisit(const MeshFacet& rclFacet, + const MeshFacet& rclFrom, + FacetIndex ulFInd, + unsigned long ulLevel, + unsigned short neighbourIndex) { (void)rclFacet; (void)rclFrom; @@ -75,32 +80,40 @@ public: /** * Special mesh visitor that searches for facets within a given search radius. */ -class MeshExport MeshSearchNeighbourFacetsVisitor : public MeshFacetVisitor +class MeshExport MeshSearchNeighbourFacetsVisitor: public MeshFacetVisitor { public: - MeshSearchNeighbourFacetsVisitor (const MeshKernel &rclMesh, float fRadius, FacetIndex ulStartFacetIdx); - ~MeshSearchNeighbourFacetsVisitor () override = default; + MeshSearchNeighbourFacetsVisitor(const MeshKernel& rclMesh, + float fRadius, + FacetIndex ulStartFacetIdx); + ~MeshSearchNeighbourFacetsVisitor() override = default; /** Checks the facet if it lies inside the search radius. */ - inline bool Visit (const MeshFacet &rclFacet, const MeshFacet &rclFrom, FacetIndex ulFInd, unsigned long ulLevel) override; + inline bool Visit(const MeshFacet& rclFacet, + const MeshFacet& rclFrom, + FacetIndex ulFInd, + unsigned long ulLevel) override; /** Resets the VISIT flag of already visited facets. */ - inline std::vector GetAndReset (); + inline std::vector GetAndReset(); protected: const MeshKernel& _rclMeshBase; /**< The mesh kernel. */ - Base::Vector3f _clCenter; /**< Center. */ - float _fRadius; /**< Search radius. */ - unsigned long _ulCurrentLevel{0}; - bool _bFacetsFoundInCurrentLevel{false}; - std::vector _vecFacets; /**< Found facets. */ + Base::Vector3f _clCenter; /**< Center. */ + float _fRadius; /**< Search radius. */ + unsigned long _ulCurrentLevel {0}; + bool _bFacetsFoundInCurrentLevel {false}; + std::vector _vecFacets; /**< Found facets. */ }; -inline bool MeshSearchNeighbourFacetsVisitor::Visit (const MeshFacet &rclFacet, const MeshFacet &rclFrom, - FacetIndex ulFInd, unsigned long ulLevel) +inline bool MeshSearchNeighbourFacetsVisitor::Visit(const MeshFacet& rclFacet, + const MeshFacet& rclFrom, + FacetIndex ulFInd, + unsigned long ulLevel) { (void)rclFrom; if (ulLevel > _ulCurrentLevel) { - if (!_bFacetsFoundInCurrentLevel) + if (!_bFacetsFoundInCurrentLevel) { return false; + } _ulCurrentLevel = ulLevel; _bFacetsFoundInCurrentLevel = false; } @@ -119,14 +132,18 @@ inline bool MeshSearchNeighbourFacetsVisitor::Visit (const MeshFacet &rclFacet, /** * The MeshTopFacetVisitor just collects the indices of all visited facets. */ -class MeshExport MeshTopFacetVisitor : public MeshFacetVisitor +class MeshExport MeshTopFacetVisitor: public MeshFacetVisitor { public: - MeshTopFacetVisitor (std::vector &raulNB) : _raulNeighbours(raulNB) {} - ~MeshTopFacetVisitor () override = default; + MeshTopFacetVisitor(std::vector& raulNB) + : _raulNeighbours(raulNB) + {} + ~MeshTopFacetVisitor() override = default; /** Collects the facet indices. */ - bool Visit (const MeshFacet &rclFacet, const MeshFacet &rclFrom, - FacetIndex ulFInd, unsigned long) override + bool Visit(const MeshFacet& rclFacet, + const MeshFacet& rclFrom, + FacetIndex ulFInd, + unsigned long) override { (void)rclFacet; (void)rclFrom; @@ -135,7 +152,7 @@ public: } protected: - std::vector &_raulNeighbours; /**< Indices of all visited facets. */ + std::vector& _raulNeighbours; /**< Indices of all visited facets. */ }; // ------------------------------------------------------------------------- @@ -144,22 +161,24 @@ protected: * The MeshPlaneVisitor collects all facets the are co-planar to the plane defined * by the start triangle. */ -class MeshPlaneVisitor : public MeshFacetVisitor +class MeshPlaneVisitor: public MeshFacetVisitor { public: - MeshPlaneVisitor (const MeshKernel& mesh, - FacetIndex index, - float deviation, - std::vector &indices); - ~MeshPlaneVisitor () override; - bool AllowVisit (const MeshFacet& face, const MeshFacet&, - FacetIndex, unsigned long, unsigned short neighbourIndex) override; - bool Visit (const MeshFacet & face, const MeshFacet &, - FacetIndex ulFInd, unsigned long) override; + MeshPlaneVisitor(const MeshKernel& mesh, + FacetIndex index, + float deviation, + std::vector& indices); + ~MeshPlaneVisitor() override; + bool AllowVisit(const MeshFacet& face, + const MeshFacet&, + FacetIndex, + unsigned long, + unsigned short neighbourIndex) override; + bool Visit(const MeshFacet& face, const MeshFacet&, FacetIndex ulFInd, unsigned long) override; protected: const MeshKernel& mesh; - std::vector &indices; + std::vector& indices; Base::Vector3f basepoint; Base::Vector3f normal; float max_deviation; @@ -184,11 +203,12 @@ public: * If \a true is returned the next iteration is done if there are still point to visit. If * \a false is returned the calling method stops immediately visiting further points. */ - virtual bool Visit (const MeshPoint &rclPoint, const MeshPoint &rclFrom, - FacetIndex ulPInd, unsigned long ulLevel) = 0; + virtual bool Visit(const MeshPoint& rclPoint, + const MeshPoint& rclFrom, + FacetIndex ulPInd, + unsigned long ulLevel) = 0; }; -} // namespace MeshCore - -#endif // VISITOR_H +} // namespace MeshCore +#endif // VISITOR_H diff --git a/src/Mod/Mesh/App/Core/tritritest.h b/src/Mod/Mesh/App/Core/tritritest.h index 44d790391f..ce65c67553 100644 --- a/src/Mod/Mesh/App/Core/tritritest.h +++ b/src/Mod/Mesh/App/Core/tritritest.h @@ -1,3 +1,4 @@ +// clang-format off /* Triangle/triangle intersection test routine, * by Tomas Moller, 1997. * See article "A Fast Triangle-Triangle Intersection Test", @@ -722,3 +723,4 @@ int tri_tri_intersect_with_isectline(float V0[3],float V1[3],float V2[3], return 1; } +// clang-format on diff --git a/src/Mod/Mesh/App/Edge.cpp b/src/Mod/Mesh/App/Edge.cpp index 787cf8cf82..1fa3ff4d75 100644 --- a/src/Mod/Mesh/App/Edge.cpp +++ b/src/Mod/Mesh/App/Edge.cpp @@ -22,7 +22,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include "Edge.h" @@ -31,21 +31,21 @@ using namespace Mesh; -Edge::Edge() //NOLINT - : Mesh(nullptr) +Edge::Edge() // NOLINT + : Mesh(nullptr) { - for (int i=0; i<2; i++) { + for (int i = 0; i < 2; i++) { PIndex[i] = MeshCore::POINT_INDEX_MAX; NIndex[i] = MeshCore::FACET_INDEX_MAX; } } Edge::Edge(const Edge& e) - : MeshCore::MeshGeomEdge(e) - , Index(e.Index) - , Mesh(e.Mesh) + : MeshCore::MeshGeomEdge(e) + , Index(e.Index) + , Mesh(e.Mesh) { - for (int i=0; i<2; i++) { + for (int i = 0; i < 2; i++) { PIndex[i] = e.PIndex[i]; NIndex[i] = e.NIndex[i]; } @@ -53,12 +53,12 @@ Edge::Edge(const Edge& e) Edge::~Edge() = default; -void Edge::operator = (const Edge& e) +void Edge::operator=(const Edge& e) { - MeshCore::MeshGeomEdge::operator = (e); - Mesh = e.Mesh; + MeshCore::MeshGeomEdge::operator=(e); + Mesh = e.Mesh; Index = e.Index; - for (int i=0; i<2; i++) { + for (int i = 0; i < 2; i++) { PIndex[i] = e.PIndex[i]; NIndex[i] = e.NIndex[i]; } diff --git a/src/Mod/Mesh/App/Edge.h b/src/Mod/Mesh/App/Edge.h index 4da2c74cbc..27e7167160 100644 --- a/src/Mod/Mesh/App/Edge.h +++ b/src/Mod/Mesh/App/Edge.h @@ -38,24 +38,27 @@ class MeshObject; * convenient access to the Mesh data structure. This class should not be used * for programming algorithms in C++. Use Mesh Core classes instead! */ -class MeshExport Edge : public MeshCore::MeshGeomEdge +class MeshExport Edge: public MeshCore::MeshGeomEdge { public: Edge(); Edge(const Edge& f); ~Edge(); - bool isBound() const {return Index != -1;} + bool isBound() const + { + return Index != -1; + } void unbound(); - void operator = (const Edge& f); + void operator=(const Edge& f); - int Index{-1}; + int Index {-1}; MeshCore::PointIndex PIndex[2]; MeshCore::FacetIndex NIndex[2]; Base::Reference Mesh; }; -} // namespace Mesh +} // namespace Mesh -#endif // MESH_EDGE_H +#endif // MESH_EDGE_H diff --git a/src/Mod/Mesh/App/EdgePyImp.cpp b/src/Mod/Mesh/App/EdgePyImp.cpp index ad2b02e70b..bfed97e7b6 100644 --- a/src/Mod/Mesh/App/EdgePyImp.cpp +++ b/src/Mod/Mesh/App/EdgePyImp.cpp @@ -26,9 +26,11 @@ #include #include +// clang-format off #include "Edge.h" #include "EdgePy.h" #include "EdgePy.cpp" +// clang-format on using namespace Mesh; @@ -36,18 +38,28 @@ using namespace Mesh; // returns a string which represent the object e.g. when printed in python std::string EdgePy::representation() const { + // clang-format off EdgePy::PointerType ptr = getEdgePtr(); std::stringstream str; str << "Edge ("; - str << "(" << ptr->_aclPoints[0].x << ", " << ptr->_aclPoints[0].y << ", " << ptr->_aclPoints[0].z << ", Idx=" << ptr->PIndex[0] << "), "; - str << "(" << ptr->_aclPoints[1].x << ", " << ptr->_aclPoints[1].y << ", " << ptr->_aclPoints[1].z << ", Idx=" << ptr->PIndex[1] << "), "; - str << "Idx=" << ptr->Index << ", (" << ptr->NIndex[0] << ", " << ptr->NIndex[1] << ")"; + str << "(" << ptr->_aclPoints[0].x << ", " + << ptr->_aclPoints[0].y << ", " + << ptr->_aclPoints[0].z << ", Idx=" + << ptr->PIndex[0] << "), "; + str << "(" << ptr->_aclPoints[1].x << ", " + << ptr->_aclPoints[1].y << ", " + << ptr->_aclPoints[1].z << ", Idx=" + << ptr->PIndex[1] << "), "; + str << "Idx=" << ptr->Index << ", (" + << ptr->NIndex[0] << ", " + << ptr->NIndex[1] << ")"; str << ")"; + // clang-format on return str.str(); } -PyObject *EdgePy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper +PyObject* EdgePy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper { // create a new instance of EdgePy and the Twin object return new EdgePy(new Edge); @@ -58,28 +70,38 @@ int EdgePy::PyInit(PyObject* args, PyObject* /*kwds*/) { PyObject* pt1 = nullptr; PyObject* pt2 = nullptr; - if (!PyArg_ParseTuple(args, "|O!O!", &Base::VectorPy::Type, &pt1 - , &Base::VectorPy::Type, &pt2)) + if (!PyArg_ParseTuple(args, + "|O!O!", + &Base::VectorPy::Type, + &pt1, + &Base::VectorPy::Type, + &pt2)) { return -1; + } - if (pt1) - getEdgePtr()->_aclPoints[0] = Base::convertTo(Py::Vector(pt1, false).toVector()); - if (pt2) - getEdgePtr()->_aclPoints[1] = Base::convertTo(Py::Vector(pt2, false).toVector()); + if (pt1) { + getEdgePtr()->_aclPoints[0] = + Base::convertTo(Py::Vector(pt1, false).toVector()); + } + if (pt2) { + getEdgePtr()->_aclPoints[1] = + Base::convertTo(Py::Vector(pt2, false).toVector()); + } return 0; } Py::Long EdgePy::getIndex() const { - return Py::Long((long) getEdgePtr()->Index); + return Py::Long((long)getEdgePtr()->Index); } -PyObject* EdgePy::intersectWithEdge(PyObject *args) +PyObject* EdgePy::intersectWithEdge(PyObject* args) { PyObject* object; - if (!PyArg_ParseTuple(args, "O!", &EdgePy::Type, &object)) + if (!PyArg_ParseTuple(args, "O!", &EdgePy::Type, &object)) { return nullptr; - EdgePy *edge = static_cast(object); + } + EdgePy* edge = static_cast(object); EdgePy::PointerType edge_ptr = edge->getEdgePtr(); EdgePy::PointerType this_ptr = this->getEdgePtr(); Base::Vector3f p; @@ -101,34 +123,37 @@ PyObject* EdgePy::intersectWithEdge(PyObject *args) } } -PyObject* EdgePy::isParallel(PyObject *args) +PyObject* EdgePy::isParallel(PyObject* args) { PyObject* object; - if (!PyArg_ParseTuple(args, "O!", &EdgePy::Type, &object)) + if (!PyArg_ParseTuple(args, "O!", &EdgePy::Type, &object)) { return nullptr; - EdgePy *edge = static_cast(object); + } + EdgePy* edge = static_cast(object); EdgePy::PointerType edge_ptr = edge->getEdgePtr(); EdgePy::PointerType this_ptr = this->getEdgePtr(); bool ok = this_ptr->IsParallel(*edge_ptr); return Py::new_reference_to(Py::Boolean(ok)); } -PyObject* EdgePy::isCollinear(PyObject *args) +PyObject* EdgePy::isCollinear(PyObject* args) { PyObject* object; - if (!PyArg_ParseTuple(args, "O!", &EdgePy::Type, &object)) + if (!PyArg_ParseTuple(args, "O!", &EdgePy::Type, &object)) { return nullptr; - EdgePy *edge = static_cast(object); + } + EdgePy* edge = static_cast(object); EdgePy::PointerType edge_ptr = edge->getEdgePtr(); EdgePy::PointerType this_ptr = this->getEdgePtr(); bool ok = this_ptr->IsCollinear(*edge_ptr); return Py::new_reference_to(Py::Boolean(ok)); } -PyObject* EdgePy::unbound(PyObject *args) +PyObject* EdgePy::unbound(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } getEdgePtr()->unbound(); Py_Return; } @@ -143,7 +168,7 @@ Py::List EdgePy::getPoints() const EdgePy::PointerType edge = this->getEdgePtr(); Py::List pts; - for (const auto & pnt : edge->_aclPoints) { + for (const auto& pnt : edge->_aclPoints) { Py::Tuple pt(3); pt.setItem(0, Py::Float(pnt.x)); pt.setItem(1, Py::Float(pnt.y)); @@ -159,7 +184,7 @@ Py::Tuple EdgePy::getPointIndices() const EdgePy::PointerType edge = this->getEdgePtr(); Py::Tuple idxTuple(2); - for (int i=0; i<2; i++) { + for (int i = 0; i < 2; i++) { idxTuple.setItem(i, Py::Long(edge->PIndex[i])); } return idxTuple; @@ -170,7 +195,7 @@ Py::Tuple EdgePy::getNeighbourIndices() const EdgePy::PointerType edge = this->getEdgePtr(); Py::Tuple idxTuple(2); - for (int i=0; i<2; i++) { + for (int i = 0; i < 2; i++) { idxTuple.setItem(i, Py::Long(edge->NIndex[i])); } return idxTuple; @@ -182,12 +207,12 @@ Py::Float EdgePy::getLength() const return Py::Float(Base::Distance(edge->_aclPoints[0], edge->_aclPoints[1])); } -PyObject *EdgePy::getCustomAttributes(const char* /*attr*/) const +PyObject* EdgePy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } -int EdgePy::setCustomAttributes(const char* /*attr*/, PyObject * /*obj*/) +int EdgePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) { return 0; } diff --git a/src/Mod/Mesh/App/Exporter.cpp b/src/Mod/Mesh/App/Exporter.cpp index 8ac2eb0655..00f9a8f57a 100644 --- a/src/Mod/Mesh/App/Exporter.cpp +++ b/src/Mod/Mesh/App/Exporter.cpp @@ -22,12 +22,14 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include -# include +#include +#include +#include +#include #endif +#include "Core/IO/Writer3MF.h" +#include "Core/Iterator.h" #include #include #include @@ -38,8 +40,6 @@ #include #include #include -#include "Core/Iterator.h" -#include "Core/IO/Writer3MF.h" #include #include "Exporter.h" @@ -48,13 +48,14 @@ using namespace Mesh; using namespace MeshCore; -static std::vector -expandSubObjectNames(const App::DocumentObject *obj, - std::map > &subObjectNameCache, - int depth) +static std::vector expandSubObjectNames( + const App::DocumentObject* obj, + std::map>& subObjectNameCache, + int depth) { - if (!App::GetApplication().checkLinkDepth(depth)) + if (!App::GetApplication().checkLinkDepth(depth)) { return {}; + } auto subs = obj->getSubObjects(); if (subs.empty()) { @@ -63,28 +64,33 @@ expandSubObjectNames(const App::DocumentObject *obj, } std::vector res; - for (auto & sub : subs) { + for (auto& sub : subs) { int vis = sub.empty() ? 1 : obj->isElementVisible(sub.c_str()); - if (vis == 0) + if (vis == 0) { continue; + } auto sobj = obj->getSubObject(sub.c_str()); - if (!sobj || (vis < 0 && !sobj->Visibility.getValue())) + if (!sobj || (vis < 0 && !sobj->Visibility.getValue())) { continue; + } auto linked = sobj->getLinkedObject(true); auto it = subObjectNameCache.find(linked); - if (it == subObjectNameCache.end()) - it = subObjectNameCache.emplace( - linked, expandSubObjectNames(linked, subObjectNameCache, depth+1)).first; - for (auto & ssub : it->second) + if (it == subObjectNameCache.end()) { + it = subObjectNameCache + .emplace(linked, expandSubObjectNames(linked, subObjectNameCache, depth + 1)) + .first; + } + for (auto& ssub : it->second) { res.push_back(sub + ssub); + } } return res; } Exporter::Exporter() = default; -//static -std::string Exporter::xmlEscape(const std::string &input) +// static +std::string Exporter::xmlEscape(const std::string& input) { std::string out(input); boost::replace_all(out, "&", "&"); @@ -95,30 +101,32 @@ std::string Exporter::xmlEscape(const std::string &input) return out; } -int Exporter::addObject(App::DocumentObject *obj, float tol) +int Exporter::addObject(App::DocumentObject* obj, float tol) { int count = 0; - for (std::string & sub : expandSubObjectNames(obj, subObjectNameCache, 0)) { + for (std::string& sub : expandSubObjectNames(obj, subObjectNameCache, 0)) { Base::Matrix4D matrix; auto sobj = obj->getSubObject(sub.c_str(), nullptr, &matrix); auto linked = sobj->getLinkedObject(true, &matrix, false); auto it = meshCache.find(linked); if (it == meshCache.end()) { if (linked->isDerivedFrom(Mesh::Feature::getClassTypeId())) { - it = meshCache.emplace(linked, - static_cast(linked)->Mesh.getValue()).first; + it = meshCache.emplace(linked, static_cast(linked)->Mesh.getValue()) + .first; it->second.setTransform(matrix); } else { Base::PyGILStateLocker lock; - PyObject *pyobj = nullptr; + PyObject* pyobj = nullptr; linked->getSubObject("", &pyobj, nullptr, false); - if (!pyobj) + if (!pyobj) { continue; + } if (PyObject_TypeCheck(pyobj, &Data::ComplexGeoDataPy::Type)) { std::vector aPoints; std::vector aTopo; - auto geoData = static_cast(pyobj)->getComplexGeoDataPtr(); + auto geoData = + static_cast(pyobj)->getComplexGeoDataPtr(); geoData->getFaces(aPoints, aTopo, tol); it = meshCache.emplace(linked, MeshObject()).first; it->second.setFacets(aTopo, aPoints); @@ -130,8 +138,9 @@ int Exporter::addObject(App::DocumentObject *obj, float tol) // Add a new mesh if (it != meshCache.end()) { - if (addMesh(sobj->Label.getValue(), it->second)) + if (addMesh(sobj->Label.getValue(), it->second)) { ++count; + } } } return count; @@ -150,9 +159,8 @@ void Exporter::throwIfNoPermission(const std::string& filename) // ---------------------------------------------------------------------------- MergeExporter::MergeExporter(std::string fileName, MeshIO::Format) - :fName(fileName) -{ -} + : fName(fileName) +{} MergeExporter::~MergeExporter() { @@ -176,40 +184,42 @@ void MergeExporter::write() } } -bool MergeExporter::addMesh(const char *name, const MeshObject & mesh) +bool MergeExporter::addMesh(const char* name, const MeshObject& mesh) { auto kernel = mesh.getKernel(); kernel.Transform(mesh.getTransform()); - auto countFacets( mergingMesh.countFacets() ); + auto countFacets(mergingMesh.countFacets()); if (countFacets == 0) { mergingMesh.setKernel(kernel); - } else { + } + else { mergingMesh.addMesh(kernel); } // if the mesh already has persistent segments then use them instead unsigned long numSegm = mesh.countSegments(); unsigned long canSave = 0; - for (unsigned long i=0; i 0) { - for (unsigned long i=0; i indices = segm.getIndices(); - std::for_each( indices.begin(), indices.end(), - [countFacets] (FacetIndex &v) { - v += countFacets; - } ); + std::for_each(indices.begin(), indices.end(), [countFacets](FacetIndex& v) { + v += countFacets; + }); Segment new_segm(&mergingMesh, indices, true); new_segm.setName(segm.getName()); mergingMesh.addSegment(new_segm); } } - } else { + } + else { // now create a segment for the added mesh std::vector indices; indices.resize(mergingMesh.countFacets() - countFacets); @@ -233,10 +243,12 @@ void GuiExtension3MFProducer::initialize() { Base::PyGILStateLocker lock; PyObject* module = PyImport_ImportModule("MeshGui"); - if (module) + if (module) { Py_DECREF(module); - else + } + else { PyErr_Clear(); + } } void Extension3MFFactory::addProducer(Extension3MFProducer* ext) @@ -257,21 +269,22 @@ std::vector Extension3MFFactory::createExtensions() std::vector ext; for (const auto& it : producer) { Extension3MFPtr ptr = std::dynamic_pointer_cast(it->create()); - if (ptr) + if (ptr) { ext.push_back(ptr); + } } return ext; } std::vector Extension3MFFactory::producer; -class Exporter3MF::Private { +class Exporter3MF::Private +{ public: - explicit Private(const std::string& filename, - const std::vector& ext) - : writer3mf(filename) - , ext(ext) { - } + explicit Private(const std::string& filename, const std::vector& ext) + : writer3mf(filename) + , ext(ext) + {} MeshCore::Writer3MF writer3mf; std::vector ext; }; @@ -287,7 +300,7 @@ Exporter3MF::~Exporter3MF() write(); } -bool Exporter3MF::addMesh(const char *name, const MeshObject & mesh) +bool Exporter3MF::addMesh(const char* name, const MeshObject& mesh) { boost::ignore_unused(name); bool ok = d->writer3mf.AddMesh(mesh.getKernel(), mesh.getTransform()); @@ -312,35 +325,35 @@ void Exporter3MF::write() // ---------------------------------------------------------------------------- -ExporterAMF::ExporterAMF( std::string fileName, - const std::map &meta, - bool compress ) +ExporterAMF::ExporterAMF(std::string fileName, + const std::map& meta, + bool compress) { // ask for write permission throwIfNoPermission(fileName); Base::FileInfo fi(fileName); if (compress) { - auto *zipStreamPtr( new zipios::ZipOutputStream(fi.filePath()) ); + auto* zipStreamPtr(new zipios::ZipOutputStream(fi.filePath())); // ISO 52915 specifies that compressed AMF files are zip-compressed and // must contain the AMF XML in an entry with the same name as the // compressed file. It's OK to have other files in the zip too. - zipStreamPtr->putNextEntry( zipios::ZipCDirEntry(fi.fileName()) ); + zipStreamPtr->putNextEntry(zipios::ZipCDirEntry(fi.fileName())); // Default compression seems to work fine. outputStreamPtr = zipStreamPtr; - - } else { + } + else { outputStreamPtr = new Base::ofstream(fi, std::ios::out | std::ios::binary); } if (outputStreamPtr) { *outputStreamPtr << "\n" << "\n"; - for (auto const &metaEntry : meta) { - *outputStreamPtr << "\t" << metaEntry.second << "\n"; + for (auto const& metaEntry : meta) { + *outputStreamPtr << "\t" + << metaEntry.second << "\n"; } } } @@ -370,25 +383,28 @@ void ExporterAMF::write() class ExporterAMF::VertLess { public: - bool operator()(const Base::Vector3f &a, const Base::Vector3f &b) const + bool operator()(const Base::Vector3f& a, const Base::Vector3f& b) const { if (a.x == b.x) { if (a.y == b.y) { if (a.z == b.z) { return false; - } else { + } + else { return a.z < b.z; } - } else { + } + else { return a.y < b.y; } - } else { + } + else { return a.x < b.x; } } }; -bool ExporterAMF::addMesh(const char *name, const MeshObject & mesh) +bool ExporterAMF::addMesh(const char* name, const MeshObject& mesh) { auto kernel = mesh.getKernel(); kernel.Transform(mesh.getTransform()); @@ -397,7 +413,7 @@ bool ExporterAMF::addMesh(const char *name, const MeshObject & mesh) return false; } - auto numFacets( kernel.CountFacets() ); + auto numFacets(kernel.CountFacets()); if (numFacets == 0) { return false; @@ -408,12 +424,11 @@ bool ExporterAMF::addMesh(const char *name, const MeshObject & mesh) Base::SequencerLauncher seq("Saving...", 2 * numFacets + 1); *outputStreamPtr << "\t\n"; - *outputStreamPtr << "\t\t" - << xmlEscape(name) << "\n"; + *outputStreamPtr << "\t\t" << xmlEscape(name) << "\n"; *outputStreamPtr << "\t\t\n" << "\t\t\t\n"; - const MeshCore::MeshGeomFacet *facet; + const MeshCore::MeshGeomFacet* facet; // Iterate through all facets of the mesh, and construct a: // * Cache (map) of used vertices, outputting each new unique vertex to @@ -427,14 +442,14 @@ bool ExporterAMF::addMesh(const char *name, const MeshObject & mesh) std::vector facets; // For each facet in mesh - for(clIter.Begin(), clEnd.End(); clIter < clEnd; ++clIter) { + for (clIter.Begin(), clEnd.End(); clIter < clEnd; ++clIter) { facet = &(*clIter); // For each vertex in facet for (auto pnt : facet->_aclPoints) { vertItr = vertices.find(pnt); - if ( vertItr == vertices.end() ) { + if (vertItr == vertices.end()) { facets.push_back(vertexCount); vertices[pnt] = vertexCount++; @@ -442,20 +457,20 @@ bool ExporterAMF::addMesh(const char *name, const MeshObject & mesh) // Output facet *outputStreamPtr << "\t\t\t\t\n" << "\t\t\t\t\t\n"; - for ( auto j(0); j < 3; ++j) { + for (auto j(0); j < 3; ++j) { char axis('x' + j); - *outputStreamPtr << "\t\t\t\t\t\t<" << axis << '>' - << pnt[j] - << "\n"; + *outputStreamPtr << "\t\t\t\t\t\t<" << axis << '>' << pnt[j] << "\n"; } *outputStreamPtr << "\t\t\t\t\t\n" << "\t\t\t\t\n"; - } else { + } + else { facets.push_back(vertItr->second); } } - seq.next(true); // allow to cancel + seq.next(true); // allow to cancel } *outputStreamPtr << "\t\t\t\n" @@ -463,14 +478,13 @@ bool ExporterAMF::addMesh(const char *name, const MeshObject & mesh) // Now that we've output all the vertices, we can // output the facets that refer to them! - for (auto triItr(facets.begin()); triItr != facets.end(); ) { + for (auto triItr(facets.begin()); triItr != facets.end();) { *outputStreamPtr << "\t\t\t\t\n"; for (auto i(1); i < 4; ++i) { - *outputStreamPtr << "\t\t\t\t\t' - << *(triItr++) << "\n"; + *outputStreamPtr << "\t\t\t\t\t' << *(triItr++) << "\n"; } *outputStreamPtr << "\t\t\t\t\n"; - seq.next(true); // allow to cancel + seq.next(true); // allow to cancel } *outputStreamPtr << "\t\t\t\n" diff --git a/src/Mod/Mesh/App/Exporter.h b/src/Mod/Mesh/App/Exporter.h index fd42f9042e..ad49921d2c 100644 --- a/src/Mod/Mesh/App/Exporter.h +++ b/src/Mod/Mesh/App/Exporter.h @@ -27,9 +27,9 @@ #include #include -#include "MeshFeature.h" -#include "Core/MeshIO.h" #include "Core/IO/Writer3MF.h" +#include "Core/MeshIO.h" +#include "MeshFeature.h" namespace Mesh @@ -57,27 +57,27 @@ public: * @return The number of objects/subobjects that was exported from the document. See the parameter `accuracy` of ComplexGeoData::getFaces */ - int addObject(App::DocumentObject *obj, float tol); + int addObject(App::DocumentObject* obj, float tol); - virtual bool addMesh(const char *name, const MeshObject & mesh) = 0; + virtual bool addMesh(const char* name, const MeshObject& mesh) = 0; protected: /// Does some simple escaping of characters for XML-type exports - static std::string xmlEscape(const std::string &input); + static std::string xmlEscape(const std::string& input); void throwIfNoPermission(const std::string&); - std::map > subObjectNameCache; - std::map meshCache; + std::map> subObjectNameCache; + std::map meshCache; }; /// Creates a single mesh, in a file, from one or more objects -class MergeExporter : public Exporter +class MergeExporter: public Exporter { public: MergeExporter(std::string fileName, MeshCore::MeshIO::Format fmt); ~MergeExporter() override; - bool addMesh(const char *name, const MeshObject & mesh) override; + bool addMesh(const char* name, const MeshObject& mesh) override; private: /// Write the meshes of the added objects to the output file @@ -109,12 +109,12 @@ using AbstractFormatExtensionPtr = std::shared_ptr; * \brief The Extension3MF class * Abstract base class for 3MF extensions */ -class MeshExport Extension3MF : public AbstractFormatExtension +class MeshExport Extension3MF: public AbstractFormatExtension { public: using Resource = MeshCore::Resource3MF; Extension3MF() = default; - virtual Resource addMesh(const MeshObject & mesh) = 0; + virtual Resource addMesh(const MeshObject& mesh) = 0; }; using Extension3MFPtr = std::shared_ptr; @@ -137,7 +137,7 @@ using AbstractExtensionProducerPtr = std::shared_ptr; * \brief The Extension3MFProducer class * Abstract base class to create an instance of an Extension3MF. */ -class MeshExport Extension3MFProducer : public AbstractExtensionProducer +class MeshExport Extension3MFProducer: public AbstractExtensionProducer { public: Extension3MFProducer() = default; @@ -150,7 +150,7 @@ using Extension3MFProducerPtr = std::shared_ptr; * \brief The GuiExtension3MFProducer class * This class tries to load the MeshGui module to register further 3MF extensions. */ -class MeshExport GuiExtension3MFProducer : public Extension3MFProducer +class MeshExport GuiExtension3MFProducer: public Extension3MFProducer { public: GuiExtension3MFProducer() = default; @@ -180,13 +180,13 @@ private: * The constructor and destructor write the beginning and end of the 3MF, * addObject() is used to add geometry */ -class Exporter3MF : public Exporter +class Exporter3MF: public Exporter { public: Exporter3MF(std::string fileName, const std::vector& = {}); ~Exporter3MF() override; - bool addMesh(const char *name, const MeshObject & mesh) override; + bool addMesh(const char* name, const MeshObject& mesh) override; /*! * \brief SetForceModel * Forcces to write the mesh as model even if itsn't a solid. @@ -208,7 +208,7 @@ private: * The constructor and destructor write the beginning and end of the AMF, * addObject() is used to add geometry */ -class ExporterAMF : public Exporter +class ExporterAMF: public Exporter { public: /// Writes AMF header @@ -216,26 +216,26 @@ public: * meta information passed in is applied at the tag level */ ExporterAMF(std::string fileName, - const std::map &meta, + const std::map& meta, bool compress = true); /// Writes AMF footer ~ExporterAMF() override; - bool addMesh(const char *name, const MeshObject & mesh) override; + bool addMesh(const char* name, const MeshObject& mesh) override; private: /// Write the meshes of the added objects to the output file void write(); private: - std::ostream *outputStreamPtr{nullptr}; - int nextObjectIndex{0}; + std::ostream* outputStreamPtr {nullptr}; + int nextObjectIndex {0}; /// Helper for putting Base::Vector3f objects into a std::map in addMesh() class VertLess; }; // class ExporterAMF -} // namespace Mesh +} // namespace Mesh -#endif // MESH_EXPORTER_H +#endif // MESH_EXPORTER_H diff --git a/src/Mod/Mesh/App/Facet.cpp b/src/Mod/Mesh/App/Facet.cpp index 3889f50886..c4535f1edc 100644 --- a/src/Mod/Mesh/App/Facet.cpp +++ b/src/Mod/Mesh/App/Facet.cpp @@ -22,7 +22,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include "Facet.h" @@ -32,14 +32,15 @@ using namespace Mesh; Facet::Facet(const MeshCore::MeshFacet& face, const MeshObject* obj, MeshCore::FacetIndex index) - : Index(index), Mesh(obj) + : Index(index) + , Mesh(obj) { - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { PIndex[i] = face._aulPoints[i]; NIndex[i] = face._aulNeighbours[i]; } if (Mesh.isValid() && index != MeshCore::FACET_INDEX_MAX) { - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { Base::Vector3d vert = Mesh->getPoint(PIndex[i]); _aclPoints[i].Set((float)vert.x, (float)vert.y, (float)vert.z); } @@ -47,9 +48,11 @@ Facet::Facet(const MeshCore::MeshFacet& face, const MeshObject* obj, MeshCore::F } Facet::Facet(const Facet& f) - : MeshCore::MeshGeomFacet(f), Index(f.Index), Mesh(f.Mesh) + : MeshCore::MeshGeomFacet(f) + , Index(f.Index) + , Mesh(f.Mesh) { - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { PIndex[i] = f.PIndex[i]; NIndex[i] = f.NIndex[i]; } @@ -57,12 +60,12 @@ Facet::Facet(const Facet& f) Facet::~Facet() = default; -void Facet::operator = (const Facet& f) +void Facet::operator=(const Facet& f) { - MeshCore::MeshGeomFacet::operator = (f); - Mesh = f.Mesh; + MeshCore::MeshGeomFacet::operator=(f); + Mesh = f.Mesh; Index = f.Index; - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { PIndex[i] = f.PIndex[i]; NIndex[i] = f.NIndex[i]; } diff --git a/src/Mod/Mesh/App/Facet.h b/src/Mod/Mesh/App/Facet.h index b149711c00..2ca4ca038a 100644 --- a/src/Mod/Mesh/App/Facet.h +++ b/src/Mod/Mesh/App/Facet.h @@ -36,15 +36,20 @@ class MeshObject; * convenient access to the Mesh data structure. This class should not be used * for programming algorithms in C++. Use Mesh Core classes instead! */ -class MeshExport Facet : public MeshCore::MeshGeomFacet +class MeshExport Facet: public MeshCore::MeshGeomFacet { public: - explicit Facet(const MeshCore::MeshFacet& face = MeshCore::MeshFacet(), const MeshObject* obj = nullptr, MeshCore::FacetIndex index = MeshCore::FACET_INDEX_MAX); + explicit Facet(const MeshCore::MeshFacet& face = MeshCore::MeshFacet(), + const MeshObject* obj = nullptr, + MeshCore::FacetIndex index = MeshCore::FACET_INDEX_MAX); Facet(const Facet& f); ~Facet(); - bool isBound() const {return Index != MeshCore::FACET_INDEX_MAX;} - void operator = (const Facet& f); + bool isBound() const + { + return Index != MeshCore::FACET_INDEX_MAX; + } + void operator=(const Facet& f); Edge getEdge(int) const; MeshCore::FacetIndex Index; @@ -53,7 +58,7 @@ public: Base::Reference Mesh; }; -} // namespace Mesh +} // namespace Mesh -#endif // MESH_FACET_H +#endif // MESH_FACET_H diff --git a/src/Mod/Mesh/App/FacetPyImp.cpp b/src/Mod/Mesh/App/FacetPyImp.cpp index f710801eb8..eb8ca46032 100644 --- a/src/Mod/Mesh/App/FacetPyImp.cpp +++ b/src/Mod/Mesh/App/FacetPyImp.cpp @@ -25,22 +25,26 @@ #include #include +// clang-format off #include "Facet.h" #include "FacetPy.h" #include "FacetPy.cpp" #include "EdgePy.h" #include "Mesh.h" +// clang-format on using namespace Mesh; -namespace { -class Index { +namespace +{ +class Index +{ FacetIndex index; public: Index(FacetIndex index) - : index{index} + : index {index} {} friend std::ostream& operator<<(std::ostream& os, Index idx) @@ -54,11 +58,12 @@ public: return os; } }; -} +} // namespace // returns a string which represent the object e.g. when printed in python std::string FacetPy::representation() const { + // clang-format off FacetPy::PointerType ptr = getFacetPtr(); std::stringstream str; str << "Facet ("; @@ -94,9 +99,10 @@ std::string FacetPy::representation() const str << ")"; return str.str(); + // clang-format on } -PyObject *FacetPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper +PyObject* FacetPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper { // create a new instance of FacetPy and the Twin object return new FacetPy(new Facet); @@ -105,25 +111,28 @@ PyObject *FacetPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Pyth // constructor method int FacetPy::PyInit(PyObject* args, PyObject* /*kwds*/) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return -1; + } return 0; } -PyObject* FacetPy::unbound(PyObject *args) +PyObject* FacetPy::unbound(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } getFacetPtr()->Index = MeshCore::FACET_INDEX_MAX; getFacetPtr()->Mesh = nullptr; Py_Return; } -PyObject* FacetPy::getEdge(PyObject *args) +PyObject* FacetPy::getEdge(PyObject* args) { - int index{}; - if (!PyArg_ParseTuple(args, "i", &index)) + int index {}; + if (!PyArg_ParseTuple(args, "i", &index)) { return nullptr; + } Edge edge = getFacetPtr()->getEdge(index); return new EdgePy(new Edge(edge)); @@ -131,7 +140,7 @@ PyObject* FacetPy::getEdge(PyObject *args) Py::Long FacetPy::getIndex() const { - return Py::Long((long) getFacetPtr()->Index); + return Py::Long((long)getFacetPtr()->Index); } Py::Boolean FacetPy::getBound() const @@ -143,15 +152,16 @@ Py::Object FacetPy::getNormal() const { Base::VectorPy* normal = new Base::VectorPy(getFacetPtr()->GetNormal()); normal->setConst(); - return Py::Object(normal,true); + return Py::Object(normal, true); } -PyObject* FacetPy::intersect(PyObject *args) +PyObject* FacetPy::intersect(PyObject* args) { - PyObject* object{}; - if (!PyArg_ParseTuple(args, "O!", &FacetPy::Type, &object)) + PyObject* object {}; + if (!PyArg_ParseTuple(args, "O!", &FacetPy::Type, &object)) { return nullptr; - FacetPy *face = static_cast(object); + } + FacetPy* face = static_cast(object); FacetPy::PointerType face_ptr = face->getFacetPtr(); FacetPy::PointerType this_ptr = this->getFacetPtr(); Base::Vector3f p0, p1; @@ -182,11 +192,12 @@ PyObject* FacetPy::intersect(PyObject *args) } } -PyObject* FacetPy::isDegenerated(PyObject *args) +PyObject* FacetPy::isDegenerated(PyObject* args) { float fEpsilon = MeshCore::MeshDefinitions::_fMinPointDistanceP2; - if (!PyArg_ParseTuple(args, "|f", &fEpsilon)) + if (!PyArg_ParseTuple(args, "|f", &fEpsilon)) { return nullptr; + } FacetPy::PointerType face = this->getFacetPtr(); if (!face->isBound()) { @@ -198,12 +209,13 @@ PyObject* FacetPy::isDegenerated(PyObject *args) return Py::new_reference_to(Py::Boolean(tria.IsDegenerated(fEpsilon))); } -PyObject* FacetPy::isDeformed(PyObject *args) +PyObject* FacetPy::isDeformed(PyObject* args) { - float fMinAngle{}; - float fMaxAngle{}; - if (!PyArg_ParseTuple(args, "ff", &fMinAngle, &fMaxAngle)) + float fMinAngle {}; + float fMaxAngle {}; + if (!PyArg_ParseTuple(args, "ff", &fMinAngle, &fMaxAngle)) { return nullptr; + } FacetPy::PointerType face = this->getFacetPtr(); if (!face->isBound()) { @@ -236,11 +248,12 @@ Py::List FacetPy::getPoints() const Py::Tuple FacetPy::getPointIndices() const { FacetPy::PointerType face = this->getFacetPtr(); - if (!face->isBound()) - { return Py::Tuple(); } + if (!face->isBound()) { + return Py::Tuple(); + } Py::Tuple idxTuple(3); - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { idxTuple.setItem(i, Py::Long(face->PIndex[i])); } return idxTuple; @@ -254,7 +267,7 @@ Py::Tuple FacetPy::getNeighbourIndices() const } Py::Tuple idxTuple(3); - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { auto index = face->NIndex[i]; if (index < MeshCore::FACET_INDEX_MAX) { idxTuple.setItem(i, Py::Long(index)); @@ -348,14 +361,12 @@ Py::Tuple FacetPy::getInCircle() const return tuple; } -PyObject *FacetPy::getCustomAttributes(const char* /*attr*/) const +PyObject* FacetPy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } -int FacetPy::setCustomAttributes(const char* /*attr*/, PyObject * /*obj*/) +int FacetPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) { return 0; } - - diff --git a/src/Mod/Mesh/App/FeatureMeshCurvature.cpp b/src/Mod/Mesh/App/FeatureMeshCurvature.cpp index 70394e65b0..85a4cac98c 100644 --- a/src/Mod/Mesh/App/FeatureMeshCurvature.cpp +++ b/src/Mod/Mesh/App/FeatureMeshCurvature.cpp @@ -35,23 +35,25 @@ PROPERTY_SOURCE(Mesh::Curvature, App::DocumentObject) Curvature::Curvature() { - ADD_PROPERTY(Source,(nullptr)); + ADD_PROPERTY(Source, (nullptr)); ADD_PROPERTY(CurvInfo, (CurvatureInfo())); } short Curvature::mustExecute() const { - if (Source.isTouched()) + if (Source.isTouched()) { return 1; - if (Source.getValue() && Source.getValue()->isTouched()) + } + if (Source.getValue() && Source.getValue()->isTouched()) { return 1; + } return 0; } -App::DocumentObjectExecReturn *Curvature::execute() +App::DocumentObjectExecReturn* Curvature::execute() { - Mesh::Feature *pcFeat = dynamic_cast(Source.getValue()); - if(!pcFeat || pcFeat->isError()) { + Mesh::Feature* pcFeat = dynamic_cast(Source.getValue()); + if (!pcFeat || pcFeat->isError()) { return new App::DocumentObjectExecReturn("No mesh object attached."); } @@ -63,7 +65,7 @@ App::DocumentObjectExecReturn *Curvature::execute() std::vector values; values.reserve(curv.size()); - for (const auto & it : curv) { + for (const auto& it : curv) { CurvatureInfo ci; ci.cMaxCurvDir = it.cMaxCurvDir; ci.cMinCurvDir = it.cMinCurvDir; diff --git a/src/Mod/Mesh/App/FeatureMeshCurvature.h b/src/Mod/Mesh/App/FeatureMeshCurvature.h index b923950079..35a5fd2551 100644 --- a/src/Mod/Mesh/App/FeatureMeshCurvature.h +++ b/src/Mod/Mesh/App/FeatureMeshCurvature.h @@ -36,7 +36,7 @@ namespace Mesh * The Curvature class calculates the curvature values of a related mesh feature. * @author Werner Mayer */ -class MeshExport Curvature : public App::DocumentObject +class MeshExport Curvature: public App::DocumentObject { PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Curvature); @@ -49,15 +49,16 @@ public: /** @name methods override Feature */ //@{ /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; + App::DocumentObjectExecReturn* execute() override; short mustExecute() const override; /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "MeshGui::ViewProviderMeshCurvature"; } - //@} + //@} }; -} +} // namespace Mesh -#endif // Curvature_H +#endif // Curvature_H diff --git a/src/Mod/Mesh/App/FeatureMeshDefects.cpp b/src/Mod/Mesh/App/FeatureMeshDefects.cpp index aa61026193..68a95abad0 100644 --- a/src/Mod/Mesh/App/FeatureMeshDefects.cpp +++ b/src/Mod/Mesh/App/FeatureMeshDefects.cpp @@ -22,9 +22,9 @@ #include "PreCompiled.h" -#include #include "Core/Degeneration.h" #include "Core/Triangulation.h" +#include #include "FeatureMeshDefects.h" @@ -40,20 +40,21 @@ PROPERTY_SOURCE(Mesh::FixDefects, Mesh::Feature) FixDefects::FixDefects() { - ADD_PROPERTY(Source ,(nullptr)); - ADD_PROPERTY(Epsilon ,(0)); + ADD_PROPERTY(Source, (nullptr)); + ADD_PROPERTY(Epsilon, (0)); } short FixDefects::mustExecute() const { - if (Source.isTouched()) + if (Source.isTouched()) { return 1; + } return 0; } -App::DocumentObjectExecReturn *FixDefects::execute() +App::DocumentObjectExecReturn* FixDefects::execute() { - return App::DocumentObject::StdReturn; + return App::DocumentObject::StdReturn; } // ---------------------------------------------------------------------- @@ -62,11 +63,12 @@ PROPERTY_SOURCE(Mesh::HarmonizeNormals, Mesh::FixDefects) HarmonizeNormals::HarmonizeNormals() = default; -App::DocumentObjectExecReturn *HarmonizeNormals::execute() +App::DocumentObjectExecReturn* HarmonizeNormals::execute() { App::DocumentObject* link = Source.getValue(); - if (!link) + if (!link) { return new App::DocumentObjectExecReturn("No mesh linked"); + } App::Property* prop = link->getPropertyByName("Mesh"); if (prop && prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) { Mesh::PropertyMeshKernel* kernel = static_cast(prop); @@ -85,11 +87,12 @@ PROPERTY_SOURCE(Mesh::FlipNormals, Mesh::FixDefects) FlipNormals::FlipNormals() = default; -App::DocumentObjectExecReturn *FlipNormals::execute() +App::DocumentObjectExecReturn* FlipNormals::execute() { App::DocumentObject* link = Source.getValue(); - if (!link) + if (!link) { return new App::DocumentObjectExecReturn("No mesh linked"); + } App::Property* prop = link->getPropertyByName("Mesh"); if (prop && prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) { Mesh::PropertyMeshKernel* kernel = static_cast(prop); @@ -108,11 +111,12 @@ PROPERTY_SOURCE(Mesh::FixNonManifolds, Mesh::FixDefects) FixNonManifolds::FixNonManifolds() = default; -App::DocumentObjectExecReturn *FixNonManifolds::execute() +App::DocumentObjectExecReturn* FixNonManifolds::execute() { App::DocumentObject* link = Source.getValue(); - if (!link) + if (!link) { return new App::DocumentObjectExecReturn("No mesh linked"); + } App::Property* prop = link->getPropertyByName("Mesh"); if (prop && prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) { Mesh::PropertyMeshKernel* kernel = static_cast(prop); @@ -131,11 +135,12 @@ PROPERTY_SOURCE(Mesh::FixDuplicatedFaces, Mesh::FixDefects) FixDuplicatedFaces::FixDuplicatedFaces() = default; -App::DocumentObjectExecReturn *FixDuplicatedFaces::execute() +App::DocumentObjectExecReturn* FixDuplicatedFaces::execute() { App::DocumentObject* link = Source.getValue(); - if (!link) + if (!link) { return new App::DocumentObjectExecReturn("No mesh linked"); + } App::Property* prop = link->getPropertyByName("Mesh"); if (prop && prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) { Mesh::PropertyMeshKernel* kernel = static_cast(prop); @@ -154,11 +159,12 @@ PROPERTY_SOURCE(Mesh::FixDuplicatedPoints, Mesh::FixDefects) FixDuplicatedPoints::FixDuplicatedPoints() = default; -App::DocumentObjectExecReturn *FixDuplicatedPoints::execute() +App::DocumentObjectExecReturn* FixDuplicatedPoints::execute() { App::DocumentObject* link = Source.getValue(); - if (!link) + if (!link) { return new App::DocumentObjectExecReturn("No mesh linked"); + } App::Property* prop = link->getPropertyByName("Mesh"); if (prop && prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) { Mesh::PropertyMeshKernel* kernel = static_cast(prop); @@ -177,11 +183,12 @@ PROPERTY_SOURCE(Mesh::FixDegenerations, Mesh::FixDefects) FixDegenerations::FixDegenerations() = default; -App::DocumentObjectExecReturn *FixDegenerations::execute() +App::DocumentObjectExecReturn* FixDegenerations::execute() { App::DocumentObject* link = Source.getValue(); - if (!link) + if (!link) { return new App::DocumentObjectExecReturn("No mesh linked"); + } App::Property* prop = link->getPropertyByName("Mesh"); if (prop && prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) { Mesh::PropertyMeshKernel* kernel = static_cast(prop); @@ -200,22 +207,22 @@ PROPERTY_SOURCE(Mesh::FixDeformations, Mesh::FixDefects) FixDeformations::FixDeformations() { - ADD_PROPERTY(MaxAngle ,(5.0f)); + ADD_PROPERTY(MaxAngle, (5.0f)); } -App::DocumentObjectExecReturn *FixDeformations::execute() +App::DocumentObjectExecReturn* FixDeformations::execute() { App::DocumentObject* link = Source.getValue(); - if (!link) + if (!link) { return new App::DocumentObjectExecReturn("No mesh linked"); + } App::Property* prop = link->getPropertyByName("Mesh"); if (prop && prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) { Mesh::PropertyMeshKernel* kernel = static_cast(prop); std::unique_ptr mesh(new MeshObject); *mesh = kernel->getValue(); float maxAngle = Base::toRadians(MaxAngle.getValue()); - mesh->validateDeformations(maxAngle, - static_cast(Epsilon.getValue())); + mesh->validateDeformations(maxAngle, static_cast(Epsilon.getValue())); this->Mesh.setValuePtr(mesh.release()); } @@ -228,11 +235,12 @@ PROPERTY_SOURCE(Mesh::FixIndices, Mesh::FixDefects) FixIndices::FixIndices() = default; -App::DocumentObjectExecReturn *FixIndices::execute() +App::DocumentObjectExecReturn* FixIndices::execute() { App::DocumentObject* link = Source.getValue(); - if (!link) + if (!link) { return new App::DocumentObjectExecReturn("No mesh linked"); + } App::Property* prop = link->getPropertyByName("Mesh"); if (prop && prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) { Mesh::PropertyMeshKernel* kernel = static_cast(prop); @@ -251,22 +259,23 @@ PROPERTY_SOURCE(Mesh::FillHoles, Mesh::FixDefects) FillHoles::FillHoles() { - ADD_PROPERTY(FillupHolesOfLength,(0)); - ADD_PROPERTY(MaxArea,(0.1f)); + ADD_PROPERTY(FillupHolesOfLength, (0)); + ADD_PROPERTY(MaxArea, (0.1f)); } -App::DocumentObjectExecReturn *FillHoles::execute() +App::DocumentObjectExecReturn* FillHoles::execute() { App::DocumentObject* link = Source.getValue(); - if (!link) + if (!link) { return new App::DocumentObjectExecReturn("No mesh linked"); + } App::Property* prop = link->getPropertyByName("Mesh"); if (prop && prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) { Mesh::PropertyMeshKernel* kernel = static_cast(prop); std::unique_ptr mesh(new MeshObject); *mesh = kernel->getValue(); MeshCore::ConstraintDelaunayTriangulator cTria((float)MaxArea.getValue()); - //MeshCore::Triangulator cTria(mesh->getKernel()); + // MeshCore::Triangulator cTria(mesh->getKernel()); mesh->fillupHoles(FillupHolesOfLength.getValue(), 1, cTria); this->Mesh.setValuePtr(mesh.release()); } @@ -280,14 +289,15 @@ PROPERTY_SOURCE(Mesh::RemoveComponents, Mesh::FixDefects) RemoveComponents::RemoveComponents() { - ADD_PROPERTY(RemoveCompOfSize,(0)); + ADD_PROPERTY(RemoveCompOfSize, (0)); } -App::DocumentObjectExecReturn *RemoveComponents::execute() +App::DocumentObjectExecReturn* RemoveComponents::execute() { App::DocumentObject* link = Source.getValue(); - if (!link) + if (!link) { return new App::DocumentObjectExecReturn("No mesh linked"); + } App::Property* prop = link->getPropertyByName("Mesh"); if (prop && prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) { Mesh::PropertyMeshKernel* kernel = static_cast(prop); diff --git a/src/Mod/Mesh/App/FeatureMeshDefects.h b/src/Mod/Mesh/App/FeatureMeshDefects.h index 00efe63dd9..abbce7c23a 100644 --- a/src/Mod/Mesh/App/FeatureMeshDefects.h +++ b/src/Mod/Mesh/App/FeatureMeshDefects.h @@ -35,229 +35,230 @@ namespace Mesh * The FixDefects class fixes defects in the attached mesh kernel. * @author Werner Mayer */ -class MeshExport FixDefects : public Mesh::Feature +class MeshExport FixDefects: public Mesh::Feature { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FixDefects); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FixDefects); public: - /// Constructor - FixDefects(); + /// Constructor + FixDefects(); - /** @name Properties */ - //@{ - App::PropertyLink Source; - App::PropertyFloat Epsilon; - //@} + /** @name Properties */ + //@{ + App::PropertyLink Source; + App::PropertyFloat Epsilon; + //@} - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - short mustExecute() const override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + short mustExecute() const override; + //@} - /// returns the type name of the ViewProvider -// virtual const char* getViewProviderName(void) const {return "MeshGui::ViewProviderDefects";} + /// returns the type name of the ViewProvider + // virtual const char* getViewProviderName(void) const {return "MeshGui::ViewProviderDefects";} }; /** * The HarmonizeNormals class harmonizes the normals of the faces. * @author Werner Mayer */ -class MeshExport HarmonizeNormals : public Mesh::FixDefects +class MeshExport HarmonizeNormals: public Mesh::FixDefects { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::HarmonizeNormals); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::HarmonizeNormals); public: - /// Constructor - HarmonizeNormals(); + /// Constructor + HarmonizeNormals(); - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + //@} }; /** * The FlipNormals class flips the normals of all faces. * @author Werner Mayer */ -class MeshExport FlipNormals : public Mesh::FixDefects +class MeshExport FlipNormals: public Mesh::FixDefects { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FlipNormals); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FlipNormals); public: - /// Constructor - FlipNormals(); + /// Constructor + FlipNormals(); - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + //@} }; /** * The FixNonManifolds class tries to fix edges with more than two faces attached. * @author Werner Mayer */ -class MeshExport FixNonManifolds : public Mesh::FixDefects +class MeshExport FixNonManifolds: public Mesh::FixDefects { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FixNonManifolds); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FixNonManifolds); public: - /// Constructor - FixNonManifolds(); + /// Constructor + FixNonManifolds(); - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + //@} }; /** * The FixDuplicatedFaces class removes duplicated faces from the mesh. * @author Werner Mayer */ -class MeshExport FixDuplicatedFaces : public Mesh::FixDefects +class MeshExport FixDuplicatedFaces: public Mesh::FixDefects { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FixDuplicatedFaces); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FixDuplicatedFaces); public: - /// Constructor - FixDuplicatedFaces(); + /// Constructor + FixDuplicatedFaces(); - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + //@} }; /** * The FixDuplicatedPoints class removes duplicated points from the mesh. * @author Werner Mayer */ -class MeshExport FixDuplicatedPoints : public Mesh::FixDefects +class MeshExport FixDuplicatedPoints: public Mesh::FixDefects { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FixDuplicatedPoints); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FixDuplicatedPoints); public: - /// Constructor - FixDuplicatedPoints(); + /// Constructor + FixDuplicatedPoints(); - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + //@} }; /** * The FixDegenerations class removes degenerated faces from the mesh. * @author Werner Mayer */ -class MeshExport FixDegenerations : public Mesh::FixDefects +class MeshExport FixDegenerations: public Mesh::FixDefects { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FixDegenerations); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FixDegenerations); public: - /// Constructor - FixDegenerations(); + /// Constructor + FixDegenerations(); - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + //@} }; /** * The FixDeformations class tries to repair deformed faces by swapping edge operations. * @author Werner Mayer */ -class MeshExport FixDeformations : public Mesh::FixDefects +class MeshExport FixDeformations: public Mesh::FixDefects { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FixDeformations); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FixDeformations); public: - /// Constructor - FixDeformations(); + /// Constructor + FixDeformations(); - /** @name Properties */ - //@{ - App::PropertyFloat MaxAngle; /**< Maximum allowed angle */ - //@} - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - //@} + /** @name Properties */ + //@{ + App::PropertyFloat MaxAngle; /**< Maximum allowed angle */ + //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + //@} }; /** * The FixIndices class tries to validate invalid indices of the internal mesh data structure. * @author Werner Mayer */ -class MeshExport FixIndices : public Mesh::FixDefects +class MeshExport FixIndices: public Mesh::FixDefects { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FixIndices); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FixIndices); public: - /// Constructor - FixIndices(); + /// Constructor + FixIndices(); - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + //@} }; /** * The FillHoles class tries to fill up holes in the internal mesh data structure. * @author Werner Mayer */ -class MeshExport FillHoles : public Mesh::FixDefects +class MeshExport FillHoles: public Mesh::FixDefects { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FillHoles); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::FillHoles); public: - /// Constructor - FillHoles(); - App::PropertyInteger FillupHolesOfLength; - App::PropertyFloat MaxArea; + /// Constructor + FillHoles(); + App::PropertyInteger FillupHolesOfLength; + App::PropertyFloat MaxArea; - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + //@} }; /** - * The RemoveComponents class removes topologic independent components up to a certain size from the mesh data structure. + * The RemoveComponents class removes topologic independent components up to a certain size from the + * mesh data structure. * @author Werner Mayer */ -class MeshExport RemoveComponents : public Mesh::FixDefects +class MeshExport RemoveComponents: public Mesh::FixDefects { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::RemoveComponents); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::RemoveComponents); public: - /// Constructor - RemoveComponents(); - App::PropertyInteger RemoveCompOfSize; + /// Constructor + RemoveComponents(); + App::PropertyInteger RemoveCompOfSize; - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + //@} }; -} //namespace Mesh +} // namespace Mesh -#endif // MESH_FEATURE_MESH_DEFECTS_H +#endif // MESH_FEATURE_MESH_DEFECTS_H diff --git a/src/Mod/Mesh/App/FeatureMeshExport.cpp b/src/Mod/Mesh/App/FeatureMeshExport.cpp index 0ac9ae5007..81682c889c 100644 --- a/src/Mod/Mesh/App/FeatureMeshExport.cpp +++ b/src/Mod/Mesh/App/FeatureMeshExport.cpp @@ -41,20 +41,23 @@ Export::Export() short Export::mustExecute() const { if (Source.getValue()) { - if (Source.isTouched()) + if (Source.isTouched()) { return 1; - if (FileName.isTouched()) + } + if (FileName.isTouched()) { return 1; - if (Format.isTouched()) + } + if (Format.isTouched()) { return 1; + } } return 0; } -App::DocumentObjectExecReturn *Export::execute() +App::DocumentObjectExecReturn* Export::execute() { - Mesh::Feature *pcFeat = dynamic_cast(Source.getValue()); - if(!pcFeat || pcFeat->isError()) { + Mesh::Feature* pcFeat = dynamic_cast(Source.getValue()); + if (!pcFeat || pcFeat->isError()) { return new App::DocumentObjectExecReturn("Cannot export invalid mesh feature"); } diff --git a/src/Mod/Mesh/App/FeatureMeshExport.h b/src/Mod/Mesh/App/FeatureMeshExport.h index 28647652ea..90498cb5ca 100644 --- a/src/Mod/Mesh/App/FeatureMeshExport.h +++ b/src/Mod/Mesh/App/FeatureMeshExport.h @@ -27,7 +27,7 @@ #include #ifndef MESH_GLOBAL_H -# include +#include #endif namespace Mesh @@ -37,28 +37,29 @@ namespace Mesh * The Export class writes any supported mesh format into a file. * @author Werner Mayer */ -class MeshExport Export : public App::DocumentObject +class MeshExport Export: public App::DocumentObject { PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Export); public: Export(); - App::PropertyLink Source; + App::PropertyLink Source; App::PropertyString FileName; App::PropertyString Format; - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "MeshGui::ViewProviderExport"; } /** @name methods override feature */ //@{ /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; + App::DocumentObjectExecReturn* execute() override; short mustExecute() const override; //@} }; -} +} // namespace Mesh -#endif // MESH_FEATUREMESHEXPORT_H +#endif // MESH_FEATUREMESHEXPORT_H diff --git a/src/Mod/Mesh/App/FeatureMeshImport.cpp b/src/Mod/Mesh/App/FeatureMeshImport.cpp index b16d173df8..c7b0612178 100644 --- a/src/Mod/Mesh/App/FeatureMeshImport.cpp +++ b/src/Mod/Mesh/App/FeatureMeshImport.cpp @@ -31,18 +31,20 @@ using namespace MeshCore; PROPERTY_SOURCE(Mesh::Import, Mesh::Feature) -Mesh::Import::Import() { +Mesh::Import::Import() +{ ADD_PROPERTY(FileName, ("")); } short Mesh::Import::mustExecute() const { - if (FileName.isTouched()) + if (FileName.isTouched()) { return 1; + } return 0; } -App::DocumentObjectExecReturn *Mesh::Import::execute() +App::DocumentObjectExecReturn* Mesh::Import::execute() { std::unique_ptr apcKernel(new MeshObject()); apcKernel->load(FileName.getValue()); @@ -50,4 +52,3 @@ App::DocumentObjectExecReturn *Mesh::Import::execute() return App::DocumentObject::StdReturn; } - diff --git a/src/Mod/Mesh/App/FeatureMeshImport.h b/src/Mod/Mesh/App/FeatureMeshImport.h index c73dc6aa54..90c45ce9f8 100644 --- a/src/Mod/Mesh/App/FeatureMeshImport.h +++ b/src/Mod/Mesh/App/FeatureMeshImport.h @@ -36,23 +36,23 @@ namespace Mesh * into the FreeCAD workspace. * @author Werner Mayer */ -class Import : public Mesh::Feature +class Import: public Mesh::Feature { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Import); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Import); public: - Import(); + Import(); - App::PropertyFile FileName; + App::PropertyFile FileName; - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - short mustExecute() const override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + short mustExecute() const override; + //@} }; -} +} // namespace Mesh -#endif // FEATURE_MESH_IMPORT_H +#endif // FEATURE_MESH_IMPORT_H diff --git a/src/Mod/Mesh/App/FeatureMeshSegmentByMesh.cpp b/src/Mod/Mesh/App/FeatureMeshSegmentByMesh.cpp index 61fb3d625e..5df89ecef7 100644 --- a/src/Mod/Mesh/App/FeatureMeshSegmentByMesh.cpp +++ b/src/Mod/Mesh/App/FeatureMeshSegmentByMesh.cpp @@ -46,30 +46,36 @@ SegmentByMesh::SegmentByMesh() short SegmentByMesh::mustExecute() const { - if (Source.isTouched() || Tool.isTouched()) + if (Source.isTouched() || Tool.isTouched()) { return 1; - if (Source.getValue() && Source.getValue()->isTouched()) + } + if (Source.getValue() && Source.getValue()->isTouched()) { return 1; - if (Tool.getValue() && Tool.getValue()->isTouched()) + } + if (Tool.getValue() && Tool.getValue()->isTouched()) { return 1; + } return 0; } -App::DocumentObjectExecReturn *SegmentByMesh::execute() +App::DocumentObjectExecReturn* SegmentByMesh::execute() { - Mesh::PropertyMeshKernel *kernel=nullptr; + Mesh::PropertyMeshKernel* kernel = nullptr; App::DocumentObject* mesh = Source.getValue(); if (mesh) { App::Property* prop = mesh->getPropertyByName("Mesh"); - if (prop && prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) + if (prop && prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) { kernel = static_cast(prop); + } } - if (!kernel) + if (!kernel) { return new App::DocumentObjectExecReturn("No mesh specified.\n"); - else if (mesh->isError()) + } + else if (mesh->isError()) { return new App::DocumentObjectExecReturn("No valid mesh.\n"); + } - Mesh::PropertyMeshKernel *toolmesh=nullptr; + Mesh::PropertyMeshKernel* toolmesh = nullptr; App::DocumentObject* tool = Tool.getValue(); if (tool) { App::Property* prop = tool->getPropertyByName("Mesh"); @@ -86,12 +92,12 @@ App::DocumentObjectExecReturn *SegmentByMesh::execute() // the clipping plane Base::Vector3f cBase, cNormal; - cBase = Base::convertTo(Base.getValue()); + cBase = Base::convertTo(Base.getValue()); cNormal = Base::convertTo(Normal.getValue()); const MeshKernel& rMeshKernel = kernel->getValue().getKernel(); - const MeshKernel& rToolMesh = toolmesh->getValue().getKernel(); + const MeshKernel& rToolMesh = toolmesh->getValue().getKernel(); // check if the toolmesh is a solid if (!MeshEvalSolid(rToolMesh).Evaluate()) { @@ -102,15 +108,17 @@ App::DocumentObjectExecReturn *SegmentByMesh::execute() std::vector aFaces; MeshAlgorithm cAlg(rMeshKernel); - if (cNormal.Length() > 0.1f) // not a null vector + if (cNormal.Length() > 0.1f) { // not a null vector cAlg.GetFacetsFromToolMesh(rToolMesh, cNormal, faces); - else + } + else { cAlg.GetFacetsFromToolMesh(rToolMesh, Base::Vector3f(0.0, 1.0f, 0.0f), faces); + } // if the clipping plane was set then we want only the visible facets - if ( cNormal.Length() > 0.1f ) { // not a null vector - // now we have too many facets since we have (invisible) facets near to the back clipping plane, - // so we need the nearest facet to the front clipping plane + if (cNormal.Length() > 0.1f) { // not a null vector + // now we have too many facets since we have (invisible) facets near to the back clipping + // plane, so we need the nearest facet to the front clipping plane // float fDist = FLOAT_MAX; MeshCore::FacetIndex uIdx = MeshCore::FACET_INDEX_MAX; @@ -119,17 +127,17 @@ App::DocumentObjectExecReturn *SegmentByMesh::execute() // get the nearest facet to the user (front clipping plane) for (MeshCore::FacetIndex it : faces) { cFIt.Set(it); - float dist = (float)fabs(cFIt->GetGravityPoint().DistanceToPlane( cBase, cNormal )); - if ( dist < fDist ) { + float dist = (float)fabs(cFIt->GetGravityPoint().DistanceToPlane(cBase, cNormal)); + if (dist < fDist) { fDist = dist; uIdx = it; } } // succeeded - if ( uIdx != MeshCore::FACET_INDEX_MAX ) { + if (uIdx != MeshCore::FACET_INDEX_MAX) { // set VISIT-Flag to all outer facets - cAlg.SetFacetFlag( MeshFacet::VISIT ); + cAlg.SetFacetFlag(MeshFacet::VISIT); cAlg.ResetFacetsFlag(faces, MeshFacet::VISIT); faces.clear(); @@ -141,8 +149,9 @@ App::DocumentObjectExecReturn *SegmentByMesh::execute() } } - for (MeshCore::FacetIndex it : faces) - aFaces.push_back( rMeshKernel.GetFacet(it) ); + for (MeshCore::FacetIndex it : faces) { + aFaces.push_back(rMeshKernel.GetFacet(it)); + } std::unique_ptr pcKernel(new MeshObject); pcKernel->addFacets(aFaces); @@ -150,4 +159,3 @@ App::DocumentObjectExecReturn *SegmentByMesh::execute() return App::DocumentObject::StdReturn; } - diff --git a/src/Mod/Mesh/App/FeatureMeshSegmentByMesh.h b/src/Mod/Mesh/App/FeatureMeshSegmentByMesh.h index 17cdc9ae2b..7732fac57f 100644 --- a/src/Mod/Mesh/App/FeatureMeshSegmentByMesh.h +++ b/src/Mod/Mesh/App/FeatureMeshSegmentByMesh.h @@ -36,27 +36,27 @@ namespace Mesh * the facets of the first mesh that lie inside the second mesh build up the segment. * @author Werner Mayer */ -class SegmentByMesh : public Mesh::Feature +class SegmentByMesh: public Mesh::Feature { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::SegmentByMesh); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::SegmentByMesh); public: - SegmentByMesh(); + SegmentByMesh(); - App::PropertyLink Source; - App::PropertyLink Tool; - App::PropertyVector Base; - App::PropertyVector Normal; + App::PropertyLink Source; + App::PropertyLink Tool; + App::PropertyVector Base; + App::PropertyVector Normal; - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - short mustExecute() const override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + short mustExecute() const override; + //@} }; -} +} // namespace Mesh -#endif // FEATURE_MESH_SEGMENTBYMESH_H +#endif // FEATURE_MESH_SEGMENTBYMESH_H diff --git a/src/Mod/Mesh/App/FeatureMeshSetOperations.cpp b/src/Mod/Mesh/App/FeatureMeshSetOperations.cpp index 40ebc203db..7ba08f5c84 100644 --- a/src/Mod/Mesh/App/FeatureMeshSetOperations.cpp +++ b/src/Mod/Mesh/App/FeatureMeshSetOperations.cpp @@ -44,57 +44,70 @@ SetOperations::SetOperations() short SetOperations::mustExecute() const { if (Source1.getValue() && Source2.getValue()) { - if (Source1.isTouched()) + if (Source1.isTouched()) { return 1; - if (Source2.isTouched()) + } + if (Source2.isTouched()) { return 1; - if (OperationType.isTouched()) + } + if (OperationType.isTouched()) { return 1; + } } return 0; } -App::DocumentObjectExecReturn *SetOperations::execute() +App::DocumentObjectExecReturn* SetOperations::execute() { - Mesh::Feature *mesh1 = dynamic_cast(Source1.getValue()); - Mesh::Feature *mesh2 = dynamic_cast(Source2.getValue()); + Mesh::Feature* mesh1 = dynamic_cast(Source1.getValue()); + Mesh::Feature* mesh2 = dynamic_cast(Source2.getValue()); if (mesh1 && mesh2) { const MeshObject& meshKernel1 = mesh1->Mesh.getValue(); const MeshObject& meshKernel2 = mesh2->Mesh.getValue(); - std::unique_ptr pcKernel(new MeshObject()); // Result Meshkernel + std::unique_ptr pcKernel(new MeshObject()); // Result Meshkernel MeshCore::SetOperations::OperationType type; string ot(OperationType.getValue()); - if (ot == "union") + if (ot == "union") { type = MeshCore::SetOperations::Union; - else if (ot == "intersection") + } + else if (ot == "intersection") { type = MeshCore::SetOperations::Intersect; - else if (ot == "difference") + } + else if (ot == "difference") { type = MeshCore::SetOperations::Difference; - else if (ot == "inner") + } + else if (ot == "inner") { type = MeshCore::SetOperations::Inner; - else if (ot == "outer") + } + else if (ot == "outer") { type = MeshCore::SetOperations::Outer; - else + } + else { throw Base::ValueError("Operation type must either be 'union' or 'intersection'" " or 'difference' or 'inner' or 'outer'"); + } - MeshCore::SetOperations setOp(meshKernel1.getKernel(), meshKernel2.getKernel(), - pcKernel->getKernel(), type, 1.0e-5f); + MeshCore::SetOperations setOp(meshKernel1.getKernel(), + meshKernel2.getKernel(), + pcKernel->getKernel(), + type, + 1.0e-5f); setOp.Do(); Mesh.setValuePtr(pcKernel.release()); } else { // Error mesh property - if (!mesh1) + if (!mesh1) { throw Base::ValueError("First input mesh not set"); - if (!mesh2) + } + if (!mesh2) { throw Base::ValueError("Second input mesh not set"); + } } return App::DocumentObject::StdReturn; } - diff --git a/src/Mod/Mesh/App/FeatureMeshSetOperations.h b/src/Mod/Mesh/App/FeatureMeshSetOperations.h index bd6a9a1d40..f43fc45255 100644 --- a/src/Mod/Mesh/App/FeatureMeshSetOperations.h +++ b/src/Mod/Mesh/App/FeatureMeshSetOperations.h @@ -36,25 +36,25 @@ namespace Mesh * Operations so far: Intersections, Union, Difference * @author Berthold Grupp */ -class SetOperations : public Mesh::Feature +class SetOperations: public Mesh::Feature { PROPERTY_HEADER_WITH_OVERRIDE(Mesh::SetOperations); public: SetOperations(); - App::PropertyLink Source1; - App::PropertyLink Source2; + App::PropertyLink Source1; + App::PropertyLink Source2; App::PropertyString OperationType; /** @name methods override Feature */ //@{ /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; + App::DocumentObjectExecReturn* execute() override; short mustExecute() const override; //@} }; -} +} // namespace Mesh -#endif // FEATURE_MESH_SEGMENT_H +#endif // FEATURE_MESH_SEGMENT_H diff --git a/src/Mod/Mesh/App/FeatureMeshSolid.cpp b/src/Mod/Mesh/App/FeatureMeshSolid.cpp index 03407d3905..3115cef31e 100644 --- a/src/Mod/Mesh/App/FeatureMeshSolid.cpp +++ b/src/Mod/Mesh/App/FeatureMeshSolid.cpp @@ -27,10 +27,11 @@ #include "FeatureMeshSolid.h" -namespace Mesh { - const App::PropertyIntegerConstraint::Constraints intSampling = {0, INT_MAX, 1}; - const App::PropertyLength::Constraints floatRange = {0.0, FLT_MAX, 1.0}; -} +namespace Mesh +{ +const App::PropertyIntegerConstraint::Constraints intSampling = {0, INT_MAX, 1}; +const App::PropertyLength::Constraints floatRange = {0.0, FLT_MAX, 1.0}; +} // namespace Mesh using namespace Mesh; using namespace MeshCore; @@ -47,14 +48,16 @@ Sphere::Sphere() short Sphere::mustExecute() const { - if (Radius.isTouched() || Sampling.isTouched()) + if (Radius.isTouched() || Sampling.isTouched()) { return 1; + } return Feature::mustExecute(); } -App::DocumentObjectExecReturn *Sphere::execute() +App::DocumentObjectExecReturn* Sphere::execute() { - std::unique_ptr mesh(MeshObject::createSphere((float)Radius.getValue(),Sampling.getValue())); + std::unique_ptr mesh( + MeshObject::createSphere((float)Radius.getValue(), Sampling.getValue())); if (mesh.get()) { mesh->setPlacement(this->Placement.getValue()); Mesh.setValue(mesh->getKernel()); @@ -65,7 +68,9 @@ App::DocumentObjectExecReturn *Sphere::execute() } } -void Sphere::handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property *prop) +void Sphere::handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) { if (prop == &Radius && strcmp(TypeName, "App::PropertyFloatConstraint") == 0) { App::PropertyFloatConstraint r; @@ -83,9 +88,9 @@ PROPERTY_SOURCE(Mesh::Ellipsoid, Mesh::Feature) Ellipsoid::Ellipsoid() { - ADD_PROPERTY(Radius1 ,(2.0)); - ADD_PROPERTY(Radius2 ,(4.0)); - ADD_PROPERTY(Sampling ,(50)); + ADD_PROPERTY(Radius1, (2.0)); + ADD_PROPERTY(Radius2, (4.0)); + ADD_PROPERTY(Sampling, (50)); Radius1.setConstraints(&floatRange); Radius2.setConstraints(&floatRange); Sampling.setConstraints(&intSampling); @@ -93,16 +98,17 @@ Ellipsoid::Ellipsoid() short Ellipsoid::mustExecute() const { - if (Radius1.isTouched() || - Radius2.isTouched() || - Sampling.isTouched()) + if (Radius1.isTouched() || Radius2.isTouched() || Sampling.isTouched()) { return 1; + } return Feature::mustExecute(); } -App::DocumentObjectExecReturn *Ellipsoid::execute() +App::DocumentObjectExecReturn* Ellipsoid::execute() { - std::unique_ptr mesh(MeshObject::createEllipsoid((float)Radius1.getValue(),(float)Radius2.getValue(),Sampling.getValue())); + std::unique_ptr mesh(MeshObject::createEllipsoid((float)Radius1.getValue(), + (float)Radius2.getValue(), + Sampling.getValue())); if (mesh.get()) { mesh->setPlacement(this->Placement.getValue()); Mesh.setValue(mesh->getKernel()); @@ -113,10 +119,12 @@ App::DocumentObjectExecReturn *Ellipsoid::execute() } } -void Ellipsoid::handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property *prop) +void Ellipsoid::handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) { - if ((prop == &Radius1 || prop == &Radius2) && - strcmp(TypeName, "App::PropertyFloatConstraint") == 0) { + if ((prop == &Radius1 || prop == &Radius2) + && strcmp(TypeName, "App::PropertyFloatConstraint") == 0) { App::PropertyFloatConstraint r; r.Restore(reader); static_cast(prop)->setValue(r.getValue()); @@ -132,11 +140,11 @@ PROPERTY_SOURCE(Mesh::Cylinder, Mesh::Feature) Cylinder::Cylinder() { - ADD_PROPERTY(Radius ,(2.0)); - ADD_PROPERTY(Length ,(10.0)); - ADD_PROPERTY(EdgeLength,(1.0)); - ADD_PROPERTY(Closed ,(true)); - ADD_PROPERTY(Sampling ,(50)); + ADD_PROPERTY(Radius, (2.0)); + ADD_PROPERTY(Length, (10.0)); + ADD_PROPERTY(EdgeLength, (1.0)); + ADD_PROPERTY(Closed, (true)); + ADD_PROPERTY(Sampling, (50)); Radius.setConstraints(&floatRange); Length.setConstraints(&floatRange); EdgeLength.setConstraints(&floatRange); @@ -145,19 +153,20 @@ Cylinder::Cylinder() short Cylinder::mustExecute() const { - if (Radius.isTouched() || - Length.isTouched() || - EdgeLength.isTouched() || - Closed.isTouched() || - Sampling.isTouched()) + if (Radius.isTouched() || Length.isTouched() || EdgeLength.isTouched() || Closed.isTouched() + || Sampling.isTouched()) { return 1; + } return Feature::mustExecute(); } -App::DocumentObjectExecReturn *Cylinder::execute() +App::DocumentObjectExecReturn* Cylinder::execute() { - std::unique_ptr mesh(MeshObject::createCylinder((float)Radius.getValue(),(float)Length.getValue(), - Closed.getValue(),(float)EdgeLength.getValue(),Sampling.getValue())); + std::unique_ptr mesh(MeshObject::createCylinder((float)Radius.getValue(), + (float)Length.getValue(), + Closed.getValue(), + (float)EdgeLength.getValue(), + Sampling.getValue())); if (mesh.get()) { mesh->setPlacement(this->Placement.getValue()); Mesh.setValue(mesh->getKernel()); @@ -168,10 +177,12 @@ App::DocumentObjectExecReturn *Cylinder::execute() } } -void Cylinder::handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property *prop) +void Cylinder::handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) { - if ((prop == &Radius || prop == &Length || prop == &EdgeLength) && - strcmp(TypeName, "App::PropertyFloatConstraint") == 0) { + if ((prop == &Radius || prop == &Length || prop == &EdgeLength) + && strcmp(TypeName, "App::PropertyFloatConstraint") == 0) { App::PropertyFloatConstraint r; r.Restore(reader); static_cast(prop)->setValue(r.getValue()); @@ -187,12 +198,12 @@ PROPERTY_SOURCE(Mesh::Cone, Mesh::Feature) Cone::Cone() { - ADD_PROPERTY(Radius1 ,(2.0)); - ADD_PROPERTY(Radius2 ,(4.0)); - ADD_PROPERTY(Length ,(10.0)); - ADD_PROPERTY(EdgeLength,(1.0)); - ADD_PROPERTY(Closed ,(true)); - ADD_PROPERTY(Sampling ,(50)); + ADD_PROPERTY(Radius1, (2.0)); + ADD_PROPERTY(Radius2, (4.0)); + ADD_PROPERTY(Length, (10.0)); + ADD_PROPERTY(EdgeLength, (1.0)); + ADD_PROPERTY(Closed, (true)); + ADD_PROPERTY(Sampling, (50)); Radius1.setConstraints(&floatRange); Radius2.setConstraints(&floatRange); Length.setConstraints(&floatRange); @@ -202,20 +213,21 @@ Cone::Cone() short Cone::mustExecute() const { - if (Radius1.isTouched() || - Radius2.isTouched() || - Length.isTouched() || - EdgeLength.isTouched() || - Closed.isTouched() || - Sampling.isTouched()) + if (Radius1.isTouched() || Radius2.isTouched() || Length.isTouched() || EdgeLength.isTouched() + || Closed.isTouched() || Sampling.isTouched()) { return 1; + } return Feature::mustExecute(); } -App::DocumentObjectExecReturn *Cone::execute() +App::DocumentObjectExecReturn* Cone::execute() { - std::unique_ptr mesh(MeshObject::createCone((float)Radius1.getValue(),(float)Radius2.getValue(),(float)Length.getValue(), - Closed.getValue(),(float)EdgeLength.getValue(),Sampling.getValue())); + std::unique_ptr mesh(MeshObject::createCone((float)Radius1.getValue(), + (float)Radius2.getValue(), + (float)Length.getValue(), + Closed.getValue(), + (float)EdgeLength.getValue(), + Sampling.getValue())); if (mesh.get()) { mesh->setPlacement(this->Placement.getValue()); Mesh.setValue(mesh->getKernel()); @@ -226,10 +238,12 @@ App::DocumentObjectExecReturn *Cone::execute() } } -void Cone::handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property *prop) +void Cone::handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) { - if ((prop == &Radius1 || prop == &Radius2 || prop == &Length || prop == &EdgeLength) && - strcmp(TypeName, "App::PropertyFloatConstraint") == 0) { + if ((prop == &Radius1 || prop == &Radius2 || prop == &Length || prop == &EdgeLength) + && strcmp(TypeName, "App::PropertyFloatConstraint") == 0) { App::PropertyFloatConstraint r; r.Restore(reader); static_cast(prop)->setValue(r.getValue()); @@ -245,9 +259,9 @@ PROPERTY_SOURCE(Mesh::Torus, Mesh::Feature) Torus::Torus() { - ADD_PROPERTY(Radius1 ,(10.0)); - ADD_PROPERTY(Radius2 ,(2.0)); - ADD_PROPERTY(Sampling ,(50)); + ADD_PROPERTY(Radius1, (10.0)); + ADD_PROPERTY(Radius2, (2.0)); + ADD_PROPERTY(Sampling, (50)); Radius1.setConstraints(&floatRange); Radius2.setConstraints(&floatRange); Sampling.setConstraints(&intSampling); @@ -255,16 +269,17 @@ Torus::Torus() short Torus::mustExecute() const { - if (Radius1.isTouched() || - Radius2.isTouched() || - Sampling.isTouched()) + if (Radius1.isTouched() || Radius2.isTouched() || Sampling.isTouched()) { return 1; + } return Feature::mustExecute(); } -App::DocumentObjectExecReturn *Torus::execute() +App::DocumentObjectExecReturn* Torus::execute() { - std::unique_ptr mesh(MeshObject::createTorus((float)Radius1.getValue(),(float)Radius2.getValue(),Sampling.getValue())); + std::unique_ptr mesh(MeshObject::createTorus((float)Radius1.getValue(), + (float)Radius2.getValue(), + Sampling.getValue())); if (mesh.get()) { mesh->setPlacement(this->Placement.getValue()); Mesh.setValue(mesh->getKernel()); @@ -275,10 +290,12 @@ App::DocumentObjectExecReturn *Torus::execute() } } -void Torus::handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property *prop) +void Torus::handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) { - if ((prop == &Radius1 || prop == &Radius2) && - strcmp(TypeName, "App::PropertyFloatConstraint") == 0) { + if ((prop == &Radius1 || prop == &Radius2) + && strcmp(TypeName, "App::PropertyFloatConstraint") == 0) { App::PropertyFloatConstraint r; r.Restore(reader); static_cast(prop)->setValue(r.getValue()); @@ -294,9 +311,9 @@ PROPERTY_SOURCE(Mesh::Cube, Mesh::Feature) Cube::Cube() { - ADD_PROPERTY_TYPE(Length,(10.0f),"Cube",App::Prop_None,"The length of the cube"); - ADD_PROPERTY_TYPE(Width ,(10.0f),"Cube",App::Prop_None,"The width of the cube"); - ADD_PROPERTY_TYPE(Height,(10.0f),"Cube",App::Prop_None,"The height of the cube"); + ADD_PROPERTY_TYPE(Length, (10.0f), "Cube", App::Prop_None, "The length of the cube"); + ADD_PROPERTY_TYPE(Width, (10.0f), "Cube", App::Prop_None, "The width of the cube"); + ADD_PROPERTY_TYPE(Height, (10.0f), "Cube", App::Prop_None, "The height of the cube"); Length.setConstraints(&floatRange); Width.setConstraints(&floatRange); Height.setConstraints(&floatRange); @@ -304,16 +321,17 @@ Cube::Cube() short Cube::mustExecute() const { - if (Length.isTouched() || - Width.isTouched() || - Height.isTouched()) + if (Length.isTouched() || Width.isTouched() || Height.isTouched()) { return 1; + } return Feature::mustExecute(); } -App::DocumentObjectExecReturn *Cube::execute() +App::DocumentObjectExecReturn* Cube::execute() { - std::unique_ptr mesh(MeshObject::createCube((float)Length.getValue(),(float)Width.getValue(),(float)Height.getValue())); + std::unique_ptr mesh(MeshObject::createCube((float)Length.getValue(), + (float)Width.getValue(), + (float)Height.getValue())); if (mesh.get()) { mesh->setPlacement(this->Placement.getValue()); Mesh.setValue(mesh->getKernel()); @@ -324,10 +342,12 @@ App::DocumentObjectExecReturn *Cube::execute() } } -void Cube::handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property *prop) +void Cube::handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) { - if ((prop == &Length || prop == &Width || prop == &Height) && - strcmp(TypeName, "App::PropertyFloatConstraint") == 0) { + if ((prop == &Length || prop == &Width || prop == &Height) + && strcmp(TypeName, "App::PropertyFloatConstraint") == 0) { App::PropertyFloatConstraint r; r.Restore(reader); static_cast(prop)->setValue(r.getValue()); diff --git a/src/Mod/Mesh/App/FeatureMeshSolid.h b/src/Mod/Mesh/App/FeatureMeshSolid.h index fd01af973c..f78ff18914 100644 --- a/src/Mod/Mesh/App/FeatureMeshSolid.h +++ b/src/Mod/Mesh/App/FeatureMeshSolid.h @@ -34,140 +34,152 @@ namespace Mesh /** * @author Werner Mayer */ -class Sphere : public Mesh::Feature +class Sphere: public Mesh::Feature { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Sphere); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Sphere); public: - Sphere(); + Sphere(); - App::PropertyLength Radius; - App::PropertyIntegerConstraint Sampling; + App::PropertyLength Radius; + App::PropertyIntegerConstraint Sampling; - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - short mustExecute() const override; - void handleChangedPropertyType(Base::XMLReader &reader, const char * TypeName, App::Property * prop) override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + short mustExecute() const override; + void handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) override; + //@} }; // ------------------------------------------------------------- -class Ellipsoid : public Mesh::Feature +class Ellipsoid: public Mesh::Feature { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Ellipsoid); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Ellipsoid); public: - Ellipsoid(); + Ellipsoid(); - App::PropertyLength Radius1; - App::PropertyLength Radius2; - App::PropertyIntegerConstraint Sampling; + App::PropertyLength Radius1; + App::PropertyLength Radius2; + App::PropertyIntegerConstraint Sampling; - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - short mustExecute() const override; - void handleChangedPropertyType(Base::XMLReader &reader, const char * TypeName, App::Property * prop) override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + short mustExecute() const override; + void handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) override; + //@} }; // ------------------------------------------------------------- -class Cylinder : public Mesh::Feature +class Cylinder: public Mesh::Feature { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Cylinder); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Cylinder); public: - Cylinder(); + Cylinder(); - App::PropertyLength Radius; - App::PropertyLength Length; - App::PropertyLength EdgeLength; - App::PropertyBool Closed; - App::PropertyIntegerConstraint Sampling; + App::PropertyLength Radius; + App::PropertyLength Length; + App::PropertyLength EdgeLength; + App::PropertyBool Closed; + App::PropertyIntegerConstraint Sampling; - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - short mustExecute() const override; - void handleChangedPropertyType(Base::XMLReader &reader, const char * TypeName, App::Property * prop) override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + short mustExecute() const override; + void handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) override; + //@} }; // ------------------------------------------------------------- -class Cone : public Mesh::Feature +class Cone: public Mesh::Feature { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Cone); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Cone); public: - Cone(); + Cone(); - App::PropertyLength Radius1; - App::PropertyLength Radius2; - App::PropertyLength Length; - App::PropertyLength EdgeLength; - App::PropertyBool Closed; - App::PropertyIntegerConstraint Sampling; + App::PropertyLength Radius1; + App::PropertyLength Radius2; + App::PropertyLength Length; + App::PropertyLength EdgeLength; + App::PropertyBool Closed; + App::PropertyIntegerConstraint Sampling; - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - short mustExecute() const override; - void handleChangedPropertyType(Base::XMLReader &reader, const char * TypeName, App::Property * prop) override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + short mustExecute() const override; + void handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) override; + //@} }; // ------------------------------------------------------------- -class Torus : public Mesh::Feature +class Torus: public Mesh::Feature { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Torus); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Torus); public: - Torus(); + Torus(); - App::PropertyLength Radius1; - App::PropertyLength Radius2; - App::PropertyIntegerConstraint Sampling; + App::PropertyLength Radius1; + App::PropertyLength Radius2; + App::PropertyIntegerConstraint Sampling; - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - short mustExecute() const override; - void handleChangedPropertyType(Base::XMLReader &reader, const char * TypeName, App::Property * prop) override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + short mustExecute() const override; + void handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) override; + //@} }; // ------------------------------------------------------------- -class Cube : public Mesh::Feature +class Cube: public Mesh::Feature { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Cube); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Cube); public: - Cube(); + Cube(); - App::PropertyLength Length; - App::PropertyLength Width; - App::PropertyLength Height; + App::PropertyLength Length; + App::PropertyLength Width; + App::PropertyLength Height; - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - short mustExecute() const override; - void handleChangedPropertyType(Base::XMLReader &reader, const char * TypeName, App::Property * prop) override; - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + short mustExecute() const override; + void handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) override; + //@} }; -} +} // namespace Mesh -#endif // FEATURE_MESH_SOLID_H +#endif // FEATURE_MESH_SOLID_H diff --git a/src/Mod/Mesh/App/FeatureMeshTransform.cpp b/src/Mod/Mesh/App/FeatureMeshTransform.cpp index 776c937ecc..e8c1f9574b 100644 --- a/src/Mod/Mesh/App/FeatureMeshTransform.cpp +++ b/src/Mod/Mesh/App/FeatureMeshTransform.cpp @@ -41,19 +41,18 @@ Transform::Transform() App::DocumentObjectExecReturn* Transform::execute() { -/* - Feature* pcFirst = dynamic_cast(Source.getValue()); - if (!pcFirst || pcFirst->isError()) - return new App::DocumentObjectExecReturn("Unknown Error"); + /* + Feature* pcFirst = dynamic_cast(Source.getValue()); + if (!pcFirst || pcFirst->isError()) + return new App::DocumentObjectExecReturn("Unknown Error"); - Matrix4D Matrix = Position.getValue(); + Matrix4D Matrix = Position.getValue(); - MeshCore::MeshKernel* pcKernel = - new MeshCore::MeshKernel(pcFirst->Mesh.getValue());// Result Meshkernel - pcKernel->Transform(Matrix); - Mesh.setValue(pcKernel); -*/ + MeshCore::MeshKernel* pcKernel = + new MeshCore::MeshKernel(pcFirst->Mesh.getValue());// Result Meshkernel + pcKernel->Transform(Matrix); + Mesh.setValue(pcKernel); + */ return App::DocumentObject::StdReturn; } - diff --git a/src/Mod/Mesh/App/FeatureMeshTransform.h b/src/Mod/Mesh/App/FeatureMeshTransform.h index 0690e37308..8684f2a5f6 100644 --- a/src/Mod/Mesh/App/FeatureMeshTransform.h +++ b/src/Mod/Mesh/App/FeatureMeshTransform.h @@ -36,28 +36,29 @@ namespace Mesh * into the FreeCAD workspace. * @author Werner Mayer */ -class Transform : public Mesh::Feature +class Transform: public Mesh::Feature { - PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Transform); + PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Transform); public: - Transform(); + Transform(); - App::PropertyLink Source; - App::PropertyMatrix Position; + App::PropertyLink Source; + App::PropertyMatrix Position; - /** @name methods override Feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; - /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { - return "MeshGui::ViewProviderMeshTransform"; - } - //@} + /** @name methods override Feature */ + //@{ + /// recalculate the Feature + App::DocumentObjectExecReturn* execute() override; + /// returns the type name of the ViewProvider + const char* getViewProviderName() const override + { + return "MeshGui::ViewProviderMeshTransform"; + } + //@} }; -} +} // namespace Mesh -#endif // FEATURE_MESH_TRANSFORM_H +#endif // FEATURE_MESH_TRANSFORM_H diff --git a/src/Mod/Mesh/App/FeatureMeshTransformDemolding.cpp b/src/Mod/Mesh/App/FeatureMeshTransformDemolding.cpp index 9a6e8492c5..4525a80c88 100644 --- a/src/Mod/Mesh/App/FeatureMeshTransformDemolding.cpp +++ b/src/Mod/Mesh/App/FeatureMeshTransformDemolding.cpp @@ -38,14 +38,14 @@ TransformDemolding::TransformDemolding() ADD_PROPERTY(Axis, (0.0, 0.0, 1.0)); } -App::DocumentObjectExecReturn *TransformDemolding::execute() +App::DocumentObjectExecReturn* TransformDemolding::execute() { /* Feature *pcFirst = dynamic_cast(Source.getValue()); if (!pcFirst || pcFirst->isError()) return new App::DocumentObjectExecReturn("Unknown Error"); - MeshCore::MeshKernel* pcKernel = new MeshCore::MeshKernel(pcFirst->Mesh.getValue()); // Result Meshkernel - Base::Matrix4D trans(Base::Vector3f(0, 0, 0), Axis.getValue(), Rotation.getValue()); + MeshCore::MeshKernel* pcKernel = new MeshCore::MeshKernel(pcFirst->Mesh.getValue()); // Result + Meshkernel Base::Matrix4D trans(Base::Vector3f(0, 0, 0), Axis.getValue(), Rotation.getValue()); //Matrix4D trans; //trans.rotLine(Axis.getValue(), Rotation.getValue()); pcKernel->Transform(trans); @@ -53,4 +53,3 @@ App::DocumentObjectExecReturn *TransformDemolding::execute() */ return App::DocumentObject::StdReturn; } - diff --git a/src/Mod/Mesh/App/FeatureMeshTransformDemolding.h b/src/Mod/Mesh/App/FeatureMeshTransformDemolding.h index a9dccf5d72..2020a05f48 100644 --- a/src/Mod/Mesh/App/FeatureMeshTransformDemolding.h +++ b/src/Mod/Mesh/App/FeatureMeshTransformDemolding.h @@ -34,7 +34,7 @@ namespace Mesh /** * The TransformDemolding class. */ -class TransformDemolding : public Transform +class TransformDemolding: public Transform { PROPERTY_HEADER_WITH_OVERRIDE(Mesh::TransformDemolding); @@ -48,14 +48,15 @@ public: /** @name methods override Feature */ //@{ /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; + App::DocumentObjectExecReturn* execute() override; /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "MeshGui::ViewProviderMeshTransformDemolding"; } //@} }; -} +} // namespace Mesh -#endif // FEATURE_MESH_TRANSFORM_H +#endif // FEATURE_MESH_TRANSFORM_H diff --git a/src/Mod/Mesh/App/Importer.cpp b/src/Mod/Mesh/App/Importer.cpp index 5392bd71c8..097cca3d9c 100644 --- a/src/Mod/Mesh/App/Importer.cpp +++ b/src/Mod/Mesh/App/Importer.cpp @@ -32,9 +32,8 @@ using namespace Mesh; Importer::Importer(App::Document* doc) - : document(doc) -{ -} + : document(doc) +{} void Importer::load(const std::string& fileName) { @@ -47,14 +46,14 @@ void Importer::load(const std::string& fileName) if (segmct > 1) { createMeshFromSegments(file.fileNamePure(), mat, mesh); } - else if (mat.binding == MeshCore::MeshIO::PER_VERTEX && - mat.diffuseColor.size() == mesh.countPoints()) { + else if (mat.binding == MeshCore::MeshIO::PER_VERTEX + && mat.diffuseColor.size() == mesh.countPoints()) { Feature* feature = createMesh(file.fileNamePure(), mesh); addVertexColors(feature, mat.diffuseColor); feature->purgeTouched(); } - else if (mat.binding == MeshCore::MeshIO::PER_FACE && - mat.diffuseColor.size() == mesh.countFacets()) { + else if (mat.binding == MeshCore::MeshIO::PER_FACE + && mat.diffuseColor.size() == mesh.countFacets()) { Feature* feature = createMesh(file.fileNamePure(), mesh); addFaceColors(feature, mat.diffuseColor); feature->purgeTouched(); @@ -76,30 +75,35 @@ void Importer::addFaceColors(Feature* feature, const std::vector& co addColors(feature, "FaceColors", colors); } -void Importer::addColors(Feature* feature, const std::string& property, const std::vector& colors) +void Importer::addColors(Feature* feature, + const std::string& property, + const std::vector& colors) { - App::PropertyColorList* prop = static_cast - (feature->addDynamicProperty("App::PropertyColorList", property.c_str())); + App::PropertyColorList* prop = static_cast( + feature->addDynamicProperty("App::PropertyColorList", property.c_str())); if (prop) { prop->setValues(colors); } } -void Importer::createMeshFromSegments(const std::string& name, MeshCore::Material& mat, MeshObject& mesh) +void Importer::createMeshFromSegments(const std::string& name, + MeshCore::Material& mat, + MeshObject& mesh) { unsigned long segmct = mesh.countSegments(); - for (unsigned long i=0; i segm(mesh.meshFromSegment(group.getIndices())); Feature* feature = createMesh(groupName, *segm); // if colors are set per face - if (mat.binding == MeshCore::MeshIO::PER_FACE && - mat.diffuseColor.size() == mesh.countFacets()) { + if (mat.binding == MeshCore::MeshIO::PER_FACE + && mat.diffuseColor.size() == mesh.countFacets()) { std::vector diffuseColor; diffuseColor.reserve(group.getIndices().size()); @@ -115,8 +119,8 @@ void Importer::createMeshFromSegments(const std::string& name, MeshCore::Materia Feature* Importer::createMesh(const std::string& name, MeshObject& mesh) { - Mesh::Feature *pcFeature = static_cast - (document->addObject("Mesh::Feature", name.c_str())); + Mesh::Feature* pcFeature = + static_cast(document->addObject("Mesh::Feature", name.c_str())); pcFeature->Label.setValue(name); pcFeature->Mesh.swapMesh(mesh); return pcFeature; diff --git a/src/Mod/Mesh/App/Importer.h b/src/Mod/Mesh/App/Importer.h index 1f18f46bf8..1000b19538 100644 --- a/src/Mod/Mesh/App/Importer.h +++ b/src/Mod/Mesh/App/Importer.h @@ -26,12 +26,14 @@ #include #include -namespace App { +namespace App +{ class Document; class Color; -} +} // namespace App -namespace MeshCore { +namespace MeshCore +{ struct Material; } namespace Mesh @@ -56,6 +58,6 @@ private: App::Document* document; }; -} // namespace Mesh +} // namespace Mesh -#endif // MESH_IMPORTER_H +#endif // MESH_IMPORTER_H diff --git a/src/Mod/Mesh/App/Mesh.cpp b/src/Mod/Mesh/App/Mesh.cpp index ad39700a10..65e65dd4aa 100644 --- a/src/Mod/Mesh/App/Mesh.cpp +++ b/src/Mod/Mesh/App/Mesh.cpp @@ -22,8 +22,8 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include +#include +#include #endif #include @@ -64,19 +64,21 @@ TYPESYSTEM_SOURCE(Mesh::MeshSegment, Data::Segment) MeshObject::MeshObject() = default; MeshObject::MeshObject(const MeshCore::MeshKernel& Kernel) - : _kernel(Kernel) + : _kernel(Kernel) { // copy the mesh structure } -MeshObject::MeshObject(const MeshCore::MeshKernel& Kernel, const Base::Matrix4D &Mtrx) - : _Mtrx(Mtrx),_kernel(Kernel) +MeshObject::MeshObject(const MeshCore::MeshKernel& Kernel, const Base::Matrix4D& Mtrx) + : _Mtrx(Mtrx) + , _kernel(Kernel) { // copy the mesh structure } MeshObject::MeshObject(const MeshObject& mesh) - : _Mtrx(mesh._Mtrx),_kernel(mesh._kernel) + : _Mtrx(mesh._Mtrx) + , _kernel(mesh._kernel) { // copy the mesh structure copySegments(mesh); @@ -96,10 +98,12 @@ std::vector MeshObject::getElementTypes() const unsigned long MeshObject::countSubElements(const char* Type) const { std::string element(Type); - if (element == "Mesh") + if (element == "Mesh") { return 1; - else if (element == "Segment") + } + else if (element == "Segment") { return countSegments(); + } return 0; } @@ -115,7 +119,9 @@ Data::Segment* MeshObject::getSubElement(const char* Type, unsigned long n) cons MeshSegment* segm = new MeshSegment(); segm->mesh = new MeshObject(*this); const Segment& faces = getSegment(n); - segm->segment = std::make_unique(static_cast(segm->mesh), faces.getIndices(), false); + segm->segment = std::make_unique(static_cast(segm->mesh), + faces.getIndices(), + false); return segm; } @@ -123,14 +129,15 @@ Data::Segment* MeshObject::getSubElement(const char* Type, unsigned long n) cons } void MeshObject::getFacesFromSubElement(const Data::Segment* element, - std::vector &points, - std::vector &/*pointNormals*/, - std::vector &faces) const + std::vector& points, + std::vector& /*pointNormals*/, + std::vector& faces) const { if (element && element->getTypeId() == MeshSegment::getClassTypeId()) { const MeshSegment* segm = static_cast(element); if (segm->segment) { - Base::Reference submesh(segm->mesh->meshFromSegment(segm->segment->getIndices())); + Base::Reference submesh( + segm->mesh->meshFromSegment(segm->segment->getIndices())); submesh->getFaces(points, faces, 0.0); } else { @@ -139,7 +146,7 @@ void MeshObject::getFacesFromSubElement(const Data::Segment* element, } } -void MeshObject::transformGeometry(const Base::Matrix4D &rclMat) +void MeshObject::transformGeometry(const Base::Matrix4D& rclMat) { MeshCore::MeshKernel kernel; swap(kernel); @@ -157,15 +164,16 @@ Base::Matrix4D MeshObject::getTransform() const return _Mtrx; } -Base::BoundBox3d MeshObject::getBoundBox()const +Base::BoundBox3d MeshObject::getBoundBox() const { _kernel.RecalcBoundBox(); Base::BoundBox3f Bnd = _kernel.GetBoundBox(); Base::BoundBox3d Bnd2; if (Bnd.IsValid()) { - for (int i =0 ;i<=7;i++) + for (int i = 0; i <= 7; i++) { Bnd2.Add(transformPointToOutside(Bnd.CalcPoint(Base::BoundBox3f::CORNER(i)))); + } } return Bnd2; @@ -199,7 +207,7 @@ void MeshObject::swapSegments(MeshObject& mesh) }); } -void MeshObject::operator = (const MeshObject& mesh) +void MeshObject::operator=(const MeshObject& mesh) { if (this != &mesh) { // copy the mesh structure @@ -227,7 +235,7 @@ void MeshObject::swap(MeshObject& mesh) { this->_kernel.Swap(mesh._kernel); swapSegments(mesh); - Base::Matrix4D tmp=this->_Mtrx; + Base::Matrix4D tmp = this->_Mtrx; this->_Mtrx = mesh._Mtrx; mesh._Mtrx = tmp; } @@ -258,12 +266,12 @@ unsigned long MeshObject::countFacets() const return _kernel.CountFacets(); } -unsigned long MeshObject::countEdges () const +unsigned long MeshObject::countEdges() const { return _kernel.CountEdges(); } -unsigned long MeshObject::countSegments () const +unsigned long MeshObject::countSegments() const { return this->_segments.size(); } @@ -298,9 +306,10 @@ MeshPoint MeshObject::getMeshPoint(PointIndex index) const return point; } -void MeshObject::getPoints(std::vector &Points, - std::vector &Normals, - double /*Accuracy*/, uint16_t /*flags*/) const +void MeshObject::getPoints(std::vector& Points, + std::vector& Normals, + double /*Accuracy*/, + uint16_t /*flags*/) const { Points = transformPointsToOutside(_kernel.GetPoints()); MeshCore::MeshRefNormalToPoints ptNormals(_kernel); @@ -313,19 +322,21 @@ Mesh::Facet MeshObject::getMeshFacet(FacetIndex index) const return face; } -void MeshObject::getFaces(std::vector &Points,std::vector &Topo, - double /*Accuracy*/, uint16_t /*flags*/) const +void MeshObject::getFaces(std::vector& Points, + std::vector& Topo, + double /*Accuracy*/, + uint16_t /*flags*/) const { unsigned long ctpoints = _kernel.CountPoints(); Points.reserve(ctpoints); - for (unsigned long i=0; i &Points,std::vector } } -unsigned int MeshObject::getMemSize () const +unsigned int MeshObject::getMemSize() const { return _kernel.GetMemSize(); } -void MeshObject::Save (Base::Writer &/*writer*/) const +void MeshObject::Save(Base::Writer& /*writer*/) const { // this is handled by the property class } -void MeshObject::SaveDocFile (Base::Writer &writer) const +void MeshObject::SaveDocFile(Base::Writer& writer) const { _kernel.Write(writer.Stream()); } -void MeshObject::Restore(Base::XMLReader &/*reader*/) +void MeshObject::Restore(Base::XMLReader& /*reader*/) { // this is handled by the property class } -void MeshObject::RestoreDocFile(Base::Reader &reader) +void MeshObject::RestoreDocFile(Base::Reader& reader) { load(reader); } -void MeshObject::save(const char* file, MeshCore::MeshIO::Format f, +void MeshObject::save(const char* file, + MeshCore::MeshIO::Format f, const MeshCore::Material* mat, const char* objectname) const { MeshCore::MeshOutput aWriter(this->_kernel, mat); - if (objectname) + if (objectname) { aWriter.SetObjectName(objectname); + } // go through the segment list and put them to the exporter when // the "save" flag is set std::vector groups; - for (const auto & segment : this->_segments) { + for (const auto& segment : this->_segments) { if (segment.isSaved()) { MeshCore::Group g; g.indices = segment.getIndices(); @@ -388,18 +401,20 @@ void MeshObject::save(const char* file, MeshCore::MeshIO::Format f, aWriter.SaveAny(file, f); } -void MeshObject::save(std::ostream& str, MeshCore::MeshIO::Format f, +void MeshObject::save(std::ostream& str, + MeshCore::MeshIO::Format f, const MeshCore::Material* mat, const char* objectname) const { MeshCore::MeshOutput aWriter(this->_kernel, mat); - if (objectname) + if (objectname) { aWriter.SetObjectName(objectname); + } // go through the segment list and put them to the exporter when // the "save" flag is set std::vector groups; - for (const auto & segment : this->_segments) { + for (const auto& segment : this->_segments) { if (segment.isSaved()) { MeshCore::Group g; g.indices = segment.getIndices(); @@ -417,8 +432,9 @@ bool MeshObject::load(const char* file, MeshCore::Material* mat) { MeshCore::MeshKernel kernel; MeshCore::MeshInput aReader(kernel, mat); - if (!aReader.LoadAny(file)) + if (!aReader.LoadAny(file)) { return false; + } swapKernel(kernel, aReader.GetGroupNames()); return true; @@ -428,15 +444,15 @@ bool MeshObject::load(std::istream& str, MeshCore::MeshIO::Format f, MeshCore::M { MeshCore::MeshKernel kernel; MeshCore::MeshInput aReader(kernel, mat); - if (!aReader.LoadFormat(str, f)) + if (!aReader.LoadFormat(str, f)) { return false; + } swapKernel(kernel, aReader.GetGroupNames()); return true; } -void MeshObject::swapKernel(MeshCore::MeshKernel& kernel, - const std::vector& g) +void MeshObject::swapKernel(MeshCore::MeshKernel& kernel, const std::vector& g) { _kernel.Swap(kernel); // Some file formats define several objects per file (e.g. OBJ). @@ -453,7 +469,7 @@ void MeshObject::swapKernel(MeshCore::MeshKernel& kernel, if (prop < it->_ulProp) { prop = it->_ulProp; if (!segment.empty()) { - this->_segments.emplace_back(this,segment,true); + this->_segments.emplace_back(this, segment, true); segment.clear(); } } @@ -463,7 +479,7 @@ void MeshObject::swapKernel(MeshCore::MeshKernel& kernel, // if the whole mesh is a single object then don't mark as segment if (!segment.empty() && (segment.size() < faces.size())) { - this->_segments.emplace_back(this,segment,true); + this->_segments.emplace_back(this, segment, true); } // apply the group names to the segments @@ -525,11 +541,11 @@ void MeshObject::writeInventor(std::ostream& str, float creaseangle) const Base::InventorBuilder builder(str); builder.beginSeparator(); - builder.addNode(Base::TransformItem{getTransform()}); - Base::ShapeHintsItem shapeHints{creaseangle}; + builder.addNode(Base::TransformItem {getTransform()}); + Base::ShapeHintsItem shapeHints {creaseangle}; builder.addNode(shapeHints); - builder.addNode(Base::Coordinate3Item{coords}); - builder.addNode(Base::IndexedFaceSetItem{indices}); + builder.addNode(Base::Coordinate3Item {coords}); + builder.addNode(Base::IndexedFaceSetItem {indices}); builder.endSeparator(); } @@ -543,20 +559,19 @@ void MeshObject::addFacets(const std::vector& facets) _kernel.AddFacets(facets); } -void MeshObject::addFacets(const std::vector &facets, - bool checkManifolds) +void MeshObject::addFacets(const std::vector& facets, bool checkManifolds) { _kernel.AddFacets(facets, checkManifolds); } -void MeshObject::addFacets(const std::vector &facets, +void MeshObject::addFacets(const std::vector& facets, const std::vector& points, bool checkManifolds) { _kernel.AddFacets(facets, points, checkManifolds); } -void MeshObject::addFacets(const std::vector &facets, +void MeshObject::addFacets(const std::vector& facets, const std::vector& points, bool checkManifolds) { @@ -572,8 +587,8 @@ void MeshObject::addFacets(const std::vector &facet std::vector point_v; point_v.reserve(points.size()); - for (const auto & point : points) { - Base::Vector3f p((float)point.x,(float)point.y,(float)point.z); + for (const auto& point : points) { + Base::Vector3f p((float)point.x, (float)point.y, (float)point.z); point_v.push_back(p); } @@ -585,7 +600,7 @@ void MeshObject::setFacets(const std::vector& facets) _kernel = facets; } -void MeshObject::setFacets(const std::vector &facets, +void MeshObject::setFacets(const std::vector& facets, const std::vector& points) { MeshCore::MeshFacetArray facet_v; @@ -600,8 +615,8 @@ void MeshObject::setFacets(const std::vector &facet MeshCore::MeshPointArray point_v; point_v.reserve(points.size()); - for (const auto & point : points) { - Base::Vector3f p((float)point.x,(float)point.y,(float)point.z); + for (const auto& point : points) { + Base::Vector3f p((float)point.x, (float)point.y, (float)point.z); point_v.push_back(p); } @@ -620,53 +635,59 @@ void MeshObject::addMesh(const MeshCore::MeshKernel& kernel) void MeshObject::deleteFacets(const std::vector& removeIndices) { - if (removeIndices.empty()) + if (removeIndices.empty()) { return; + } _kernel.DeleteFacets(removeIndices); deletedFacets(removeIndices); } void MeshObject::deletePoints(const std::vector& removeIndices) { - if (removeIndices.empty()) + if (removeIndices.empty()) { return; + } _kernel.DeletePoints(removeIndices); this->_segments.clear(); } void MeshObject::deletedFacets(const std::vector& remFacets) { - if (remFacets.empty()) - return; // nothing has changed - if (this->_segments.empty()) - return; // nothing to do + if (remFacets.empty()) { + return; // nothing has changed + } + if (this->_segments.empty()) { + return; // nothing to do + } // set an array with the original indices and mark the removed as MeshCore::FACET_INDEX_MAX - std::vector f_indices(_kernel.CountFacets()+remFacets.size()); + std::vector f_indices(_kernel.CountFacets() + remFacets.size()); for (FacetIndex remFacet : remFacets) { f_indices[remFacet] = MeshCore::FACET_INDEX_MAX; } FacetIndex index = 0; for (FacetIndex& it : f_indices) { - if (it == 0) + if (it == 0) { it = index++; + } } // the array serves now as LUT to set the new indices in the segments - for (auto & segment : this->_segments) { + for (auto& segment : this->_segments) { std::vector segm = segment._indices; - for (FacetIndex & jt : segm) { + for (FacetIndex& jt : segm) { jt = f_indices[jt]; } // remove the invalid indices std::sort(segm.begin(), segm.end()); - std::vector::iterator ft = std::find_if - (segm.begin(), segm.end(), [](FacetIndex v) { + std::vector::iterator ft = + std::find_if(segm.begin(), segm.end(), [](FacetIndex v) { return v == MeshCore::FACET_INDEX_MAX; }); - if (ft != segm.end()) + if (ft != segm.end()) { segm.erase(ft, segm.end()); + } segment._indices = segm; } } @@ -750,7 +771,9 @@ std::vector MeshObject::getPointsFromFacets(const std::vector(ray.first); Base::Vector3f dir = Base::toVector(ray.second); @@ -822,27 +845,27 @@ void MeshObject::updateMesh() const MeshCore::MeshAlgorithm alg(_kernel); alg.ResetFacetFlag(MeshCore::MeshFacet::SEGMENT); alg.ResetPointFlag(MeshCore::MeshPoint::SEGMENT); - for (const auto & segment : this->_segments) { - std::vector points; - points = _kernel.GetFacetPoints(segment.getIndices()); - alg.SetFacetsFlag(segment.getIndices(), MeshCore::MeshFacet::SEGMENT); - alg.SetPointsFlag(points, MeshCore::MeshPoint::SEGMENT); + for (const auto& segment : this->_segments) { + std::vector points; + points = _kernel.GetFacetPoints(segment.getIndices()); + alg.SetFacetsFlag(segment.getIndices(), MeshCore::MeshFacet::SEGMENT); + alg.SetPointsFlag(points, MeshCore::MeshPoint::SEGMENT); } } -std::vector > MeshObject::getComponents() const +std::vector> MeshObject::getComponents() const { - std::vector > segments; + std::vector> segments; MeshCore::MeshComponents comp(_kernel); - comp.SearchForComponents(MeshCore::MeshComponents::OverEdge,segments); + comp.SearchForComponents(MeshCore::MeshComponents::OverEdge, segments); return segments; } unsigned long MeshObject::countComponents() const { - std::vector > segments; + std::vector> segments; MeshCore::MeshComponents comp(_kernel); - comp.SearchForComponents(MeshCore::MeshComponents::OverEdge,segments); + comp.SearchForComponents(MeshCore::MeshComponents::OverEdge, segments); return segments.size(); } @@ -860,7 +883,7 @@ unsigned long MeshObject::getPointDegree(const std::vector& indices, const MeshCore::MeshFacetArray& faces = _kernel.GetFacets(); std::vector pointDeg(_kernel.CountPoints()); - for (const auto & face : faces) { + for (const auto& face : faces) { pointDeg[face._aulPoints[0]]++; pointDeg[face._aulPoints[1]]++; pointDeg[face._aulPoints[2]]++; @@ -881,10 +904,11 @@ unsigned long MeshObject::getPointDegree(const std::vector& indices, return countInvalids; } -void MeshObject::fillupHoles(unsigned long length, int level, +void MeshObject::fillupHoles(unsigned long length, + int level, MeshCore::AbstractPolygonTriangulator& cTria) { - std::list > aFailed; + std::list> aFailed; MeshCore::MeshTopoAlgorithm topalg(_kernel); topalg.FillupHoles(length, level, cTria, aFailed); } @@ -895,59 +919,69 @@ void MeshObject::offset(float fSize) unsigned int i = 0; // go through all the vertex normals - for (std::vector::iterator It= normals.begin();It != normals.end();++It,i++) + for (std::vector::iterator It = normals.begin(); It != normals.end(); + ++It, i++) { // and move each mesh point in the normal direction - _kernel.MovePoint(i,It->Normalize() * fSize); + _kernel.MovePoint(i, It->Normalize() * fSize); + } _kernel.RecalcBoundBox(); } void MeshObject::offsetSpecial2(float fSize) { Base::Builder3D builder; - std::vector PointNormals= _kernel.CalcVertexNormals(); + std::vector PointNormals = _kernel.CalcVertexNormals(); std::vector FaceNormals; std::set fliped; MeshCore::MeshFacetIterator it(_kernel); - for (it.Init(); it.More(); it.Next()) + for (it.Init(); it.More(); it.Next()) { FaceNormals.push_back(it->GetNormal().Normalize()); + } unsigned int i = 0; // go through all the vertex normals - for (std::vector::iterator It= PointNormals.begin();It != PointNormals.end();++It,i++) { - Base::Line3f line{_kernel.GetPoint(i), _kernel.GetPoint(i) + It->Normalize() * fSize}; + for (std::vector::iterator It = PointNormals.begin(); It != PointNormals.end(); + ++It, i++) { + Base::Line3f line {_kernel.GetPoint(i), _kernel.GetPoint(i) + It->Normalize() * fSize}; Base::DrawStyle drawStyle; - builder.addNode(Base::LineItem{line, drawStyle}); + builder.addNode(Base::LineItem {line, drawStyle}); // and move each mesh point in the normal direction - _kernel.MovePoint(i,It->Normalize() * fSize); + _kernel.MovePoint(i, It->Normalize() * fSize); } _kernel.RecalcBoundBox(); MeshCore::MeshTopoAlgorithm alg(_kernel); - for (int l= 0; l<1 ;l++) { - for ( it.Init(),i=0; it.More(); it.Next(),i++) { - if (it->IsFlag(MeshCore::MeshFacet::INVALID)) + for (int l = 0; l < 1; l++) { + for (it.Init(), i = 0; it.More(); it.Next(), i++) { + if (it->IsFlag(MeshCore::MeshFacet::INVALID)) { continue; + } // calculate the angle between them - float angle = acos((FaceNormals[i] * it->GetNormal()) / (it->GetNormal().Length() * FaceNormals[i].Length())); + float angle = acos((FaceNormals[i] * it->GetNormal()) + / (it->GetNormal().Length() * FaceNormals[i].Length())); if (angle > 1.6) { Base::DrawStyle drawStyle; drawStyle.pointSize = 4.0F; - Base::PointItem item{it->GetGravityPoint(), drawStyle, Base::ColorRGB{1.0F, 0.0F, 0.0F}}; + Base::PointItem item {it->GetGravityPoint(), + drawStyle, + Base::ColorRGB {1.0F, 0.0F, 0.0F}}; builder.addNode(item); fliped.insert(it.Position()); } } // if there are no flipped triangles -> stop - //int f =fliped.size(); - if (fliped.empty()) + // int f =fliped.size(); + if (fliped.empty()) { break; + } - for(FacetIndex It : fliped) + for (FacetIndex It : fliped) { alg.CollapseFacet(It); + } fliped.clear(); } @@ -955,7 +989,7 @@ void MeshObject::offsetSpecial2(float fSize) // search for intersected facets MeshCore::MeshEvalSelfIntersection eval(_kernel); - std::vector > faces; + std::vector> faces; eval.GetIntersections(faces); builder.saveToLog(); } @@ -966,15 +1000,16 @@ void MeshObject::offsetSpecial(float fSize, float zmax, float zmin) unsigned int i = 0; // go through all the vertex normals - for (std::vector::iterator It= normals.begin();It != normals.end();++It,i++) { + for (std::vector::iterator It = normals.begin(); It != normals.end(); + ++It, i++) { Base::Vector3f Pnt = _kernel.GetPoint(i); if (Pnt.z < zmax && Pnt.z > zmin) { Pnt.z = 0; - _kernel.MovePoint(i,Pnt.Normalize() * fSize); + _kernel.MovePoint(i, Pnt.Normalize() * fSize); } else { // and move each mesh point in the normal direction - _kernel.MovePoint(i,It->Normalize() * fSize); + _kernel.MovePoint(i, It->Normalize() * fSize); } } } @@ -1054,15 +1089,17 @@ std::vector MeshObject::getPointNormals() const return normals; } -void MeshObject::crossSections(const std::vector& planes, std::vector §ions, - float fMinEps, bool bConnectPolygons) const +void MeshObject::crossSections(const std::vector& planes, + std::vector& sections, + float fMinEps, + bool bConnectPolygons) const { MeshCore::MeshKernel kernel(this->_kernel); kernel.Transform(this->_Mtrx); MeshCore::MeshFacetGrid grid(kernel); MeshCore::MeshAlgorithm algo(kernel); - for (const auto & plane : planes) { + for (const auto& plane : planes) { MeshObject::TPolylines polylines; algo.CutWithPlane(plane.first, plane.second, grid, polylines, fMinEps, bConnectPolygons); sections.push_back(polylines); @@ -1070,7 +1107,8 @@ void MeshObject::crossSections(const std::vector& planes, st } void MeshObject::cut(const Base::Polygon2d& polygon2d, - const Base::ViewProjMethod& proj, MeshObject::CutType type) + const Base::ViewProjMethod& proj, + MeshObject::CutType type) { MeshCore::MeshKernel kernel(this->_kernel); kernel.Transform(getTransform()); @@ -1080,25 +1118,27 @@ void MeshObject::cut(const Base::Polygon2d& polygon2d, bool inner; switch (type) { - case INNER: - inner = true; - break; - case OUTER: - inner = false; - break; - default: - inner = true; - break; + case INNER: + inner = true; + break; + case OUTER: + inner = false; + break; + default: + inner = true; + break; } MeshCore::MeshFacetGrid meshGrid(kernel); meshAlg.CheckFacets(meshGrid, &proj, polygon2d, inner, check); - if (!check.empty()) + if (!check.empty()) { this->deleteFacets(check); + } } void MeshObject::trim(const Base::Polygon2d& polygon2d, - const Base::ViewProjMethod& proj, MeshObject::CutType type) + const Base::ViewProjMethod& proj, + MeshObject::CutType type) { MeshCore::MeshKernel kernel(this->_kernel); kernel.Transform(getTransform()); @@ -1108,26 +1148,28 @@ void MeshObject::trim(const Base::Polygon2d& polygon2d, std::vector triangle; switch (type) { - case INNER: - trim.SetInnerOrOuter(MeshCore::MeshTrimming::INNER); - break; - case OUTER: - trim.SetInnerOrOuter(MeshCore::MeshTrimming::OUTER); - break; + case INNER: + trim.SetInnerOrOuter(MeshCore::MeshTrimming::INNER); + break; + case OUTER: + trim.SetInnerOrOuter(MeshCore::MeshTrimming::OUTER); + break; } MeshCore::MeshFacetGrid meshGrid(kernel); trim.CheckFacets(meshGrid, check); trim.TrimFacets(check, triangle); - if (!check.empty()) + if (!check.empty()) { this->deleteFacets(check); + } // Re-add some triangles if (!triangle.empty()) { Base::Matrix4D mat(getTransform()); mat.inverse(); - for (auto& it : triangle) + for (auto& it : triangle) { it.Transform(mat); + } this->_kernel.AddFacets(triangle); } } @@ -1149,10 +1191,12 @@ void MeshObject::trimByPlane(const Base::Vector3f& base, const Base::Vector3f& n MeshCore::MeshFacetGrid meshGrid(this->_kernel); trim.CheckFacets(meshGrid, basePlane, normalPlane, trimFacets, removeFacets); trim.TrimFacets(trimFacets, basePlane, normalPlane, triangle); - if (!removeFacets.empty()) + if (!removeFacets.empty()) { this->deleteFacets(removeFacets); - if (!triangle.empty()) + } + if (!triangle.empty()) { this->_kernel.AddFacets(triangle); + } } MeshObject* MeshObject::unite(const MeshObject& mesh) const @@ -1162,8 +1206,11 @@ MeshObject* MeshObject::unite(const MeshObject& mesh) const kernel1.Transform(this->_Mtrx); MeshCore::MeshKernel kernel2(mesh._kernel); kernel2.Transform(mesh._Mtrx); - MeshCore::SetOperations setOp(kernel1, kernel2, result, - MeshCore::SetOperations::Union, Epsilon); + MeshCore::SetOperations setOp(kernel1, + kernel2, + result, + MeshCore::SetOperations::Union, + Epsilon); setOp.Do(); return new MeshObject(result); } @@ -1175,8 +1222,11 @@ MeshObject* MeshObject::intersect(const MeshObject& mesh) const kernel1.Transform(this->_Mtrx); MeshCore::MeshKernel kernel2(mesh._kernel); kernel2.Transform(mesh._Mtrx); - MeshCore::SetOperations setOp(kernel1, kernel2, result, - MeshCore::SetOperations::Intersect, Epsilon); + MeshCore::SetOperations setOp(kernel1, + kernel2, + result, + MeshCore::SetOperations::Intersect, + Epsilon); setOp.Do(); return new MeshObject(result); } @@ -1188,8 +1238,11 @@ MeshObject* MeshObject::subtract(const MeshObject& mesh) const kernel1.Transform(this->_Mtrx); MeshCore::MeshKernel kernel2(mesh._kernel); kernel2.Transform(mesh._Mtrx); - MeshCore::SetOperations setOp(kernel1, kernel2, result, - MeshCore::SetOperations::Difference, Epsilon); + MeshCore::SetOperations setOp(kernel1, + kernel2, + result, + MeshCore::SetOperations::Difference, + Epsilon); setOp.Do(); return new MeshObject(result); } @@ -1201,8 +1254,11 @@ MeshObject* MeshObject::inner(const MeshObject& mesh) const kernel1.Transform(this->_Mtrx); MeshCore::MeshKernel kernel2(mesh._kernel); kernel2.Transform(mesh._Mtrx); - MeshCore::SetOperations setOp(kernel1, kernel2, result, - MeshCore::SetOperations::Inner, Epsilon); + MeshCore::SetOperations setOp(kernel1, + kernel2, + result, + MeshCore::SetOperations::Inner, + Epsilon); setOp.Do(); return new MeshObject(result); } @@ -1214,20 +1270,23 @@ MeshObject* MeshObject::outer(const MeshObject& mesh) const kernel1.Transform(this->_Mtrx); MeshCore::MeshKernel kernel2(mesh._kernel); kernel2.Transform(mesh._Mtrx); - MeshCore::SetOperations setOp(kernel1, kernel2, result, - MeshCore::SetOperations::Outer, Epsilon); + MeshCore::SetOperations setOp(kernel1, + kernel2, + result, + MeshCore::SetOperations::Outer, + Epsilon); setOp.Do(); return new MeshObject(result); } -std::vector< std::vector > +std::vector> MeshObject::section(const MeshObject& mesh, bool connectLines, float fMinDist) const { MeshCore::MeshKernel kernel1(this->_kernel); kernel1.Transform(this->_Mtrx); MeshCore::MeshKernel kernel2(mesh._kernel); kernel2.Transform(mesh._Mtrx); - std::vector< std::vector > lines; + std::vector> lines; MeshCore::MeshIntersection sec(kernel1, kernel2, fMinDist); std::list tuple; @@ -1242,15 +1301,16 @@ MeshObject::section(const MeshObject& mesh, bool connectLines, float fMinDist) c } } else { - std::list< std::list > triple; + std::list> triple; sec.connectLines(false, tuple, triple); for (const auto& it : triple) { std::vector curve; curve.reserve(it.size()); - for (const auto& jt : it) + for (const auto& jt : it) { curve.push_back(jt.p); + } lines.push_back(curve); } } @@ -1265,10 +1325,11 @@ void MeshObject::refine() MeshCore::MeshTopoAlgorithm topalg(_kernel); // x < 30 deg => cos(x) > sqrt(3)/2 or x > 120 deg => cos(x) < -0.5 - for (unsigned long i=0; iIsDeformed(0.86f, -0.5f)) + if (!cF->IsDeformed(0.86f, -0.5f)) { topalg.InsertVertexAndSwapEdge(i, cF->GetGravityPoint(), 0.1f); + } } // clear the segments because we don't know how the new @@ -1281,8 +1342,9 @@ void MeshObject::removeNeedles(float length) unsigned long count = _kernel.CountFacets(); MeshCore::MeshRemoveNeedles eval(_kernel, length); eval.Fixup(); - if (_kernel.CountFacets() < count) + if (_kernel.CountFacets() < count) { this->_segments.clear(); + } } void MeshObject::validateCaps(float fMaxAngle, float fSplitFactor) @@ -1294,10 +1356,12 @@ void MeshObject::validateCaps(float fMaxAngle, float fSplitFactor) void MeshObject::optimizeTopology(float fMaxAngle) { MeshCore::MeshTopoAlgorithm topalg(_kernel); - if (fMaxAngle > 0.0f) + if (fMaxAngle > 0.0f) { topalg.OptimizeTopology(fMaxAngle); - else + } + else { topalg.OptimizeTopology(); + } // clear the segments because we don't know how the new // topology looks like @@ -1312,27 +1376,29 @@ void MeshObject::optimizeEdges() void MeshObject::splitEdges() { - std::vector > adjacentFacet; + std::vector> adjacentFacet; MeshCore::MeshAlgorithm alg(_kernel); alg.ResetFacetFlag(MeshCore::MeshFacet::VISIT); const MeshCore::MeshFacetArray& rFacets = _kernel.GetFacets(); - for (MeshCore::MeshFacetArray::_TConstIterator pF = rFacets.begin(); pF != rFacets.end(); ++pF) { - int id=2; + for (MeshCore::MeshFacetArray::_TConstIterator pF = rFacets.begin(); pF != rFacets.end(); + ++pF) { + int id = 2; if (pF->_aulNeighbours[id] != MeshCore::FACET_INDEX_MAX) { const MeshCore::MeshFacet& rFace = rFacets[pF->_aulNeighbours[id]]; - if (!pF->IsFlag(MeshCore::MeshFacet::VISIT) && !rFace.IsFlag(MeshCore::MeshFacet::VISIT)) { + if (!pF->IsFlag(MeshCore::MeshFacet::VISIT) + && !rFace.IsFlag(MeshCore::MeshFacet::VISIT)) { pF->SetFlag(MeshCore::MeshFacet::VISIT); rFace.SetFlag(MeshCore::MeshFacet::VISIT); - adjacentFacet.emplace_back(pF-rFacets.begin(), pF->_aulNeighbours[id]); + adjacentFacet.emplace_back(pF - rFacets.begin(), pF->_aulNeighbours[id]); } } } MeshCore::MeshFacetIterator cIter(_kernel); MeshCore::MeshTopoAlgorithm topalg(_kernel); - for (const auto & it : adjacentFacet) { + for (const auto& it : adjacentFacet) { cIter.Set(it.first); - Base::Vector3f mid = 0.5f*(cIter->_aclPoints[0]+cIter->_aclPoints[2]); + Base::Vector3f mid = 0.5f * (cIter->_aclPoints[0] + cIter->_aclPoints[2]); topalg.SplitEdge(it.first, it.second, mid); } @@ -1461,7 +1527,8 @@ MeshObject::TFacePairs MeshObject::getSelfIntersections() const return pairs; } -std::vector MeshObject::getSelfIntersections(const MeshObject::TFacePairs& facets) const +std::vector +MeshObject::getSelfIntersections(const MeshObject::TFacePairs& facets) const { MeshCore::MeshEvalSelfIntersection eval(getKernel()); using Section = std::pair; @@ -1472,16 +1539,19 @@ std::vector MeshObject::getSelfIntersections(const MeshObject::TFa lines.reserve(selfPoints.size()); Base::Matrix4D mat(getTransform()); - std::transform(selfPoints.begin(), selfPoints.end(), std::back_inserter(lines), [&mat](const Section& l){ - return Base::Line3d(mat * Base::convertTo(l.first), - mat * Base::convertTo(l.second)); - }); + std::transform(selfPoints.begin(), + selfPoints.end(), + std::back_inserter(lines), + [&mat](const Section& l) { + return Base::Line3d(mat * Base::convertTo(l.first), + mat * Base::convertTo(l.second)); + }); return lines; } void MeshObject::removeSelfIntersections() { - std::vector > selfIntersections; + std::vector> selfIntersections; MeshCore::MeshEvalSelfIntersection cMeshEval(_kernel); cMeshEval.GetIntersections(selfIntersections); @@ -1494,19 +1564,26 @@ void MeshObject::removeSelfIntersections() void MeshObject::removeSelfIntersections(const std::vector& indices) { // make sure that the number of indices is even and are in range - if (indices.size() % 2 != 0) + if (indices.size() % 2 != 0) { return; + } unsigned long cntfacets = _kernel.CountFacets(); - if (std::find_if(indices.begin(), indices.end(), [cntfacets](FacetIndex v) { - return v >= cntfacets; - }) < indices.end()) + if (std::find_if(indices.begin(), + indices.end(), + [cntfacets](FacetIndex v) { + return v >= cntfacets; + }) + < indices.end()) { return; - std::vector > selfIntersections; + } + std::vector> selfIntersections; std::vector::const_iterator it; - for (it = indices.begin(); it != indices.end(); ) { - FacetIndex id1 = *it; ++it; - FacetIndex id2 = *it; ++it; - selfIntersections.emplace_back(id1,id2); + for (it = indices.begin(); it != indices.end();) { + FacetIndex id1 = *it; + ++it; + FacetIndex id2 = *it; + ++it; + selfIntersections.emplace_back(id1, id2); } if (!selfIntersections.empty()) { @@ -1523,7 +1600,7 @@ void MeshObject::removeFoldsOnSurface() MeshCore::MeshEvalFoldOversOnSurface f_eval(_kernel); f_eval.Evaluate(); - std::vector inds = f_eval.GetIndices(); + std::vector inds = f_eval.GetIndices(); s_eval.Evaluate(); std::vector inds1 = s_eval.GetIndices(); @@ -1533,17 +1610,20 @@ void MeshObject::removeFoldsOnSurface() std::sort(inds.begin(), inds.end()); inds.erase(std::unique(inds.begin(), inds.end()), inds.end()); - if (!inds.empty()) + if (!inds.empty()) { deleteFacets(inds); + } // do this as additional check after removing folds on closed area - for (int i=0; i<5; i++) { + for (int i = 0; i < 5; i++) { MeshCore::MeshEvalFoldsOnBoundary b_eval(_kernel); - if (b_eval.Evaluate()) + if (b_eval.Evaluate()) { break; + } inds = b_eval.GetIndices(); - if (!inds.empty()) + if (!inds.empty()) { deleteFacets(inds); + } } } @@ -1584,8 +1664,9 @@ void MeshObject::mergeFacets() unsigned long count = _kernel.CountFacets(); MeshCore::MeshFixMergeFacets merge(_kernel); merge.Fixup(); - if (_kernel.CountFacets() < count) + if (_kernel.CountFacets() < count) { this->_segments.clear(); + } } void MeshObject::validateIndices() @@ -1615,8 +1696,9 @@ void MeshObject::validateIndices() fix.Fixup(); } - if (_kernel.CountFacets() < count) + if (_kernel.CountFacets() < count) { this->_segments.clear(); + } } bool MeshObject::hasInvalidNeighbourhood() const @@ -1649,10 +1731,12 @@ void MeshObject::validateDeformations(float fMaxAngle, float fEps) MeshCore::MeshFixDeformedFacets eval(_kernel, Base::toRadians(15.0f), Base::toRadians(150.0f), - fMaxAngle, fEps); + fMaxAngle, + fEps); eval.Fixup(); - if (_kernel.CountFacets() < count) + if (_kernel.CountFacets() < count) { this->_segments.clear(); + } } void MeshObject::validateDegenerations(float fEps) @@ -1660,8 +1744,9 @@ void MeshObject::validateDegenerations(float fEps) unsigned long count = _kernel.CountFacets(); MeshCore::MeshFixDegeneratedFacets eval(_kernel, fEps); eval.Fixup(); - if (_kernel.CountFacets() < count) + if (_kernel.CountFacets() < count) { this->_segments.clear(); + } } void MeshObject::removeDuplicatedPoints() @@ -1669,8 +1754,9 @@ void MeshObject::removeDuplicatedPoints() unsigned long count = _kernel.CountFacets(); MeshCore::MeshFixDuplicatePoints eval(_kernel); eval.Fixup(); - if (_kernel.CountFacets() < count) + if (_kernel.CountFacets() < count) { this->_segments.clear(); + } } void MeshObject::removeDuplicatedFacets() @@ -1678,8 +1764,9 @@ void MeshObject::removeDuplicatedFacets() unsigned long count = _kernel.CountFacets(); MeshCore::MeshFixDuplicateFacets eval(_kernel); eval.Fixup(); - if (_kernel.CountFacets() < count) + if (_kernel.CountFacets() < count) { this->_segments.clear(); + } } MeshObject* MeshObject::createMeshFromList(Py::List& list) @@ -1702,7 +1789,7 @@ MeshObject* MeshObject::createMeshFromList(Py::List& list) Base::EmptySequencer seq; std::unique_ptr mesh(new MeshObject); - //mesh->addFacets(facets); + // mesh->addFacets(facets); mesh->getKernel() = facets; return mesh.release(); } @@ -1712,9 +1799,10 @@ MeshObject* MeshObject::createSphere(float radius, int sampling) // load the 'BuildRegularGeoms' module Base::PyGILStateLocker lock; try { - Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true); - if (module.isNull()) + Py::Module module(PyImport_ImportModule("BuildRegularGeoms"), true); + if (module.isNull()) { return nullptr; + } Py::Dict dict = module.getDict(); Py::Callable call(dict.getItem("Sphere")); Py::Tuple args(2); @@ -1735,9 +1823,10 @@ MeshObject* MeshObject::createEllipsoid(float radius1, float radius2, int sampli // load the 'BuildRegularGeoms' module Base::PyGILStateLocker lock; try { - Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true); - if (module.isNull()) + Py::Module module(PyImport_ImportModule("BuildRegularGeoms"), true); + if (module.isNull()) { return nullptr; + } Py::Dict dict = module.getDict(); Py::Callable call(dict.getItem("Ellipsoid")); Py::Tuple args(3); @@ -1754,14 +1843,16 @@ MeshObject* MeshObject::createEllipsoid(float radius1, float radius2, int sampli return nullptr; } -MeshObject* MeshObject::createCylinder(float radius, float length, int closed, float edgelen, int sampling) +MeshObject* +MeshObject::createCylinder(float radius, float length, int closed, float edgelen, int sampling) { // load the 'BuildRegularGeoms' module Base::PyGILStateLocker lock; try { - Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true); - if (module.isNull()) + Py::Module module(PyImport_ImportModule("BuildRegularGeoms"), true); + if (module.isNull()) { return nullptr; + } Py::Dict dict = module.getDict(); Py::Callable call(dict.getItem("Cylinder")); Py::Tuple args(5); @@ -1780,14 +1871,20 @@ MeshObject* MeshObject::createCylinder(float radius, float length, int closed, f return nullptr; } -MeshObject* MeshObject::createCone(float radius1, float radius2, float len, int closed, float edgelen, int sampling) +MeshObject* MeshObject::createCone(float radius1, + float radius2, + float len, + int closed, + float edgelen, + int sampling) { // load the 'BuildRegularGeoms' module Base::PyGILStateLocker lock; try { - Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true); - if (module.isNull()) + Py::Module module(PyImport_ImportModule("BuildRegularGeoms"), true); + if (module.isNull()) { return nullptr; + } Py::Dict dict = module.getDict(); Py::Callable call(dict.getItem("Cone")); Py::Tuple args(6); @@ -1812,9 +1909,10 @@ MeshObject* MeshObject::createTorus(float radius1, float radius2, int sampling) // load the 'BuildRegularGeoms' module Base::PyGILStateLocker lock; try { - Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true); - if (module.isNull()) + Py::Module module(PyImport_ImportModule("BuildRegularGeoms"), true); + if (module.isNull()) { return nullptr; + } Py::Dict dict = module.getDict(); Py::Callable call(dict.getItem("Toroid")); Py::Tuple args(3); @@ -1836,9 +1934,10 @@ MeshObject* MeshObject::createCube(float length, float width, float height) // load the 'BuildRegularGeoms' module Base::PyGILStateLocker lock; try { - Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true); - if (module.isNull()) + Py::Module module(PyImport_ImportModule("BuildRegularGeoms"), true); + if (module.isNull()) { return nullptr; + } Py::Dict dict = module.getDict(); Py::Callable call(dict.getItem("Cube")); Py::Tuple args(3); @@ -1860,9 +1959,10 @@ MeshObject* MeshObject::createCube(float length, float width, float height, floa // load the 'BuildRegularGeoms' module Base::PyGILStateLocker lock; try { - Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true); - if (module.isNull()) + Py::Module module(PyImport_ImportModule("BuildRegularGeoms"), true); + if (module.isNull()) { return nullptr; + } Py::Dict dict = module.getDict(); Py::Callable call(dict.getItem("FineCube")); Py::Tuple args(4); @@ -1925,11 +2025,12 @@ void MeshObject::addSegment(const std::vector& inds) { unsigned long maxIndex = _kernel.CountFacets(); for (FacetIndex it : inds) { - if (it >= maxIndex) + if (it >= maxIndex) { throw Base::IndexError("Index out of range"); + } } - this->_segments.emplace_back(this,inds,true); + this->_segments.emplace_back(this, inds, true); } const Segment& MeshObject::getSegment(unsigned long index) const @@ -1959,29 +2060,40 @@ MeshObject* MeshObject::meshFromSegment(const std::vector& indices) } std::vector MeshObject::getSegmentsOfType(MeshObject::GeometryType type, - float dev, unsigned long minFacets) const + float dev, + unsigned long minFacets) const { std::vector segm; - if (this->_kernel.CountFacets() == 0) + if (this->_kernel.CountFacets() == 0) { return segm; + } MeshCore::MeshSegmentAlgorithm finder(this->_kernel); std::shared_ptr surf; switch (type) { - case PLANE: - surf.reset(new MeshCore::MeshDistanceGenericSurfaceFitSegment(new MeshCore::PlaneSurfaceFit, - this->_kernel, minFacets, dev)); - break; - case CYLINDER: - surf.reset(new MeshCore::MeshDistanceGenericSurfaceFitSegment(new MeshCore::CylinderSurfaceFit, - this->_kernel, minFacets, dev)); - break; - case SPHERE: - surf.reset(new MeshCore::MeshDistanceGenericSurfaceFitSegment(new MeshCore::SphereSurfaceFit, - this->_kernel, minFacets, dev)); - break; - default: - break; + case PLANE: + surf.reset( + new MeshCore::MeshDistanceGenericSurfaceFitSegment(new MeshCore::PlaneSurfaceFit, + this->_kernel, + minFacets, + dev)); + break; + case CYLINDER: + surf.reset( + new MeshCore::MeshDistanceGenericSurfaceFitSegment(new MeshCore::CylinderSurfaceFit, + this->_kernel, + minFacets, + dev)); + break; + case SPHERE: + surf.reset( + new MeshCore::MeshDistanceGenericSurfaceFitSegment(new MeshCore::SphereSurfaceFit, + this->_kernel, + minFacets, + dev)); + break; + default: + break; } if (surf.get()) { @@ -1990,7 +2102,7 @@ std::vector MeshObject::getSegmentsOfType(MeshObject::GeometryType type finder.FindSegments(surfaces); const std::vector& data = surf->GetSegments(); - for (const auto & it : data) { + for (const auto& it : data) { segm.emplace_back(this, it, false); } } @@ -2001,20 +2113,21 @@ std::vector MeshObject::getSegmentsOfType(MeshObject::GeometryType type // ---------------------------------------------------------------------------- MeshObject::const_point_iterator::const_point_iterator(const MeshObject* mesh, PointIndex index) - : _mesh(mesh), _p_it(mesh->getKernel()) + : _mesh(mesh) + , _p_it(mesh->getKernel()) { this->_p_it.Set(index); this->_p_it.Transform(_mesh->_Mtrx); this->_point.Mesh = _mesh; } -MeshObject::const_point_iterator::const_point_iterator -(const MeshObject::const_point_iterator& fi) = default; +MeshObject::const_point_iterator::const_point_iterator(const MeshObject::const_point_iterator& fi) = + default; MeshObject::const_point_iterator::~const_point_iterator() = default; -MeshObject::const_point_iterator& MeshObject::const_point_iterator::operator= -(const MeshObject::const_point_iterator& pi) = default; +MeshObject::const_point_iterator& +MeshObject::const_point_iterator::operator=(const MeshObject::const_point_iterator& pi) = default; void MeshObject::const_point_iterator::dereference() { @@ -2061,27 +2174,28 @@ MeshObject::const_point_iterator& MeshObject::const_point_iterator::operator--() // ---------------------------------------------------------------------------- MeshObject::const_facet_iterator::const_facet_iterator(const MeshObject* mesh, FacetIndex index) - : _mesh(mesh), _f_it(mesh->getKernel()) + : _mesh(mesh) + , _f_it(mesh->getKernel()) { this->_f_it.Set(index); this->_f_it.Transform(_mesh->_Mtrx); this->_facet.Mesh = _mesh; } -MeshObject::const_facet_iterator::const_facet_iterator -(const MeshObject::const_facet_iterator& fi) = default; +MeshObject::const_facet_iterator::const_facet_iterator(const MeshObject::const_facet_iterator& fi) = + default; MeshObject::const_facet_iterator::~const_facet_iterator() = default; -MeshObject::const_facet_iterator& MeshObject::const_facet_iterator::operator= -(const MeshObject::const_facet_iterator& fi) = default; +MeshObject::const_facet_iterator& +MeshObject::const_facet_iterator::operator=(const MeshObject::const_facet_iterator& fi) = default; void MeshObject::const_facet_iterator::dereference() { - this->_facet.MeshCore::MeshGeomFacet::operator = (*_f_it); + this->_facet.MeshCore::MeshGeomFacet::operator=(*_f_it); this->_facet.Index = _f_it.Position(); const MeshCore::MeshFacet& face = _f_it.GetReference(); - for (int i=0; i<3;i++) { + for (int i = 0; i < 3; i++) { this->_facet.PIndex[i] = face._aulPoints[i]; this->_facet.NIndex[i] = face._aulNeighbours[i]; } diff --git a/src/Mod/Mesh/App/Mesh.h b/src/Mod/Mesh/App/Mesh.h index ccbc5c5398..3e68073de8 100644 --- a/src/Mod/Mesh/App/Mesh.h +++ b/src/Mod/Mesh/App/Mesh.h @@ -44,16 +44,19 @@ #include "Segment.h" -namespace Py { +namespace Py +{ class List; } -namespace Base { - class Polygon2d; - class ViewProjMethod; -} +namespace Base +{ +class Polygon2d; +class ViewProjMethod; +} // namespace Base -namespace MeshCore { +namespace MeshCore +{ class AbstractPolygonTriangulator; } @@ -61,12 +64,13 @@ namespace Mesh { class MeshObject; -class MeshExport MeshSegment : public Data::Segment +class MeshExport MeshSegment: public Data::Segment { TYPESYSTEM_HEADER_WITH_OVERRIDE(); public: - std::string getName() const override { + std::string getName() const override + { return "MeshSegment"; } @@ -80,30 +84,39 @@ public: * @note Each instance of MeshObject has its own instance of a MeshKernel so it's not possible * that several instances of MeshObject manage one instance of MeshKernel. */ -class MeshExport MeshObject : public Data::ComplexGeoData +class MeshExport MeshObject: public Data::ComplexGeoData { TYPESYSTEM_HEADER_WITH_OVERRIDE(); public: - enum GeometryType {PLANE, CYLINDER, SPHERE}; - enum CutType {INNER, OUTER}; + enum GeometryType + { + PLANE, + CYLINDER, + SPHERE + }; + enum CutType + { + INNER, + OUTER + }; using TFacePair = std::pair; using TFacePairs = std::vector; // type def needed for cross-section - using TPlane = std::pair; + using TPlane = std::pair; using TPolylines = std::list>; using TRay = std::pair; using TFaceSection = std::pair; MeshObject(); explicit MeshObject(const MeshCore::MeshKernel& Kernel); - explicit MeshObject(const MeshCore::MeshKernel& Kernel, const Base::Matrix4D &Mtrx); + explicit MeshObject(const MeshCore::MeshKernel& Kernel, const Base::Matrix4D& Mtrx); MeshObject(const MeshObject&); ~MeshObject() override; - void operator = (const MeshObject&); + void operator=(const MeshObject&); /** @name Subelement management */ //@{ @@ -116,16 +129,15 @@ public: /// get the subelement by type and number Data::Segment* getSubElement(const char* Type, unsigned long) const override; /** Get faces from segment */ - void getFacesFromSubElement( - const Data::Segment*, - std::vector &Points, - std::vector &PointNormals, - std::vector &faces) const override; + void getFacesFromSubElement(const Data::Segment*, + std::vector& Points, + std::vector& PointNormals, + std::vector& faces) const override; //@} void setTransform(const Base::Matrix4D& rclTrf) override; Base::Matrix4D getTransform() const override; - void transformGeometry(const Base::Matrix4D &rclMat) override; + void transformGeometry(const Base::Matrix4D& rclMat) override; /** * Swaps the content of \a Kernel and the internal mesh kernel. @@ -139,7 +151,7 @@ public: std::string topologyInfo() const; unsigned long countPoints() const; unsigned long countFacets() const; - unsigned long countEdges () const; + unsigned long countEdges() const; unsigned long countSegments() const; bool isSolid() const; Base::Vector3d getPoint(PointIndex) const; @@ -148,11 +160,14 @@ public: double getSurface() const; double getVolume() const; /** Get points from object with given accuracy */ - void getPoints(std::vector &Points, - std::vector &Normals, - double Accuracy, uint16_t flags=0) const override; - void getFaces(std::vector &Points,std::vector &Topo, - double Accuracy, uint16_t flags=0) const override; + void getPoints(std::vector& Points, + std::vector& Normals, + double Accuracy, + uint16_t flags = 0) const override; + void getFaces(std::vector& Points, + std::vector& Topo, + double Accuracy, + uint16_t flags = 0) const override; std::vector getPointsFromFacets(const std::vector& facets) const; bool nearestFacetOnRay(const TRay& ray, double maxAngle, TFaceSection& output) const; std::vector foraminate(const TRay& ray, double maxAngle) const; @@ -160,9 +175,13 @@ public: void setKernel(const MeshCore::MeshKernel& m); MeshCore::MeshKernel& getKernel() - { return _kernel; } + { + return _kernel; + } const MeshCore::MeshKernel& getKernel() const - { return _kernel; } + { + return _kernel; + } Base::BoundBox3d getBoundBox() const override; bool getCenterOfGravity(Base::Vector3d& center) const override; @@ -170,39 +189,40 @@ public: /** @name I/O */ //@{ // Implemented from Persistence - unsigned int getMemSize () const override; - void Save (Base::Writer &writer) const override; - void SaveDocFile (Base::Writer &writer) const override; - void Restore(Base::XMLReader &reader) override; - void RestoreDocFile(Base::Reader &reader) override; - void save(const char* file,MeshCore::MeshIO::Format f=MeshCore::MeshIO::Undefined, - const MeshCore::Material* mat = nullptr, - const char* objectname = nullptr) const; - void save(std::ostream&,MeshCore::MeshIO::Format f, - const MeshCore::Material* mat = nullptr, - const char* objectname = nullptr) const; + unsigned int getMemSize() const override; + void Save(Base::Writer& writer) const override; + void SaveDocFile(Base::Writer& writer) const override; + void Restore(Base::XMLReader& reader) override; + void RestoreDocFile(Base::Reader& reader) override; + void save(const char* file, + MeshCore::MeshIO::Format f = MeshCore::MeshIO::Undefined, + const MeshCore::Material* mat = nullptr, + const char* objectname = nullptr) const; + void save(std::ostream&, + MeshCore::MeshIO::Format f, + const MeshCore::Material* mat = nullptr, + const char* objectname = nullptr) const; bool load(const char* file, MeshCore::Material* mat = nullptr); bool load(std::istream&, MeshCore::MeshIO::Format f, MeshCore::Material* mat = nullptr); // Save and load in internal format void save(std::ostream&) const; void load(std::istream&); - void writeInventor(std::ostream& str, float creaseangle=0.0f) const; + void writeInventor(std::ostream& str, float creaseangle = 0.0f) const; //@} /** @name Manipulation */ //@{ void addFacet(const MeshCore::MeshGeomFacet& facet); void addFacets(const std::vector& facets); - void addFacets(const std::vector &facets, - bool checkManifolds); - void addFacets(const std::vector &facets, + void addFacets(const std::vector& facets, bool checkManifolds); + void addFacets(const std::vector& facets, const std::vector& points, bool checkManifolds); - void addFacets(const std::vector &facets, + void addFacets(const std::vector& facets, const std::vector& points, bool checkManifolds); void setFacets(const std::vector& facets); - void setFacets(const std::vector &facets, + void setFacets(const std::vector& facets, const std::vector& points); /** * Combines two independent mesh objects. @@ -218,7 +238,7 @@ public: void addMesh(const MeshCore::MeshKernel&); void deleteFacets(const std::vector& removeIndices); void deletePoints(const std::vector& removeIndices); - std::vector > getComponents() const; + std::vector> getComponents() const; unsigned long countComponents() const; void removeComponents(unsigned long); /** @@ -228,7 +248,7 @@ public: * gives the number of points which will have a degree of zero. */ unsigned long getPointDegree(const std::vector& facets, - std::vector& point_degree) const; + std::vector& point_degree) const; void fillupHoles(unsigned long, int, MeshCore::AbstractPolygonTriangulator&); void offset(float fSize); void offsetSpecial2(float fSize); @@ -244,8 +264,10 @@ public: void decimate(int targetSize); Base::Vector3d getPointNormal(PointIndex) const; std::vector getPointNormals() const; - void crossSections(const std::vector&, std::vector §ions, - float fMinEps = 1.0e-2f, bool bConnectPolygons = false) const; + void crossSections(const std::vector&, + std::vector& sections, + float fMinEps = 1.0e-2f, + bool bConnectPolygons = false) const; void cut(const Base::Polygon2d& polygon, const Base::ViewProjMethod& proj, CutType); void trim(const Base::Polygon2d& polygon, const Base::ViewProjMethod& proj, CutType); void trimByPlane(const Base::Vector3f& base, const Base::Vector3f& normal); @@ -276,7 +298,8 @@ public: MeshObject* subtract(const MeshObject&) const; MeshObject* inner(const MeshObject&) const; MeshObject* outer(const MeshObject&) const; - std::vector< std::vector > section(const MeshObject&, bool connectLines, float fMinDist) const; + std::vector> + section(const MeshObject&, bool connectLines, float fMinDist) const; //@} /** @name Topological operations */ @@ -366,6 +389,7 @@ public: bool operator!=(const const_point_iterator& fi) const; const_point_iterator& operator++(); const_point_iterator& operator--(); + private: void dereference(); const MeshObject* _mesh; @@ -387,6 +411,7 @@ public: bool operator!=(const const_facet_iterator& fi) const; const_facet_iterator& operator++(); const_facet_iterator& operator--(); + private: void dereference(); const MeshObject* _mesh; @@ -397,20 +422,32 @@ public: /** @name Iterator */ //@{ const_point_iterator points_begin() const - { return {this, 0}; } + { + return {this, 0}; + } const_point_iterator points_end() const - { return {this, countPoints()}; } + { + return {this, countPoints()}; + } const_facet_iterator facets_begin() const - { return {this, 0}; } + { + return {this, 0}; + } const_facet_iterator facets_end() const - { return {this, countFacets()}; } + { + return {this, countFacets()}; + } using const_segment_iterator = std::vector::const_iterator; const_segment_iterator segments_begin() const - { return _segments.begin(); } + { + return _segments.begin(); + } const_segment_iterator segments_end() const - { return _segments.end(); } + { + return _segments.end(); + } //@} // friends @@ -431,7 +468,7 @@ private: static const float Epsilon; }; -} // namespace Mesh +} // namespace Mesh -#endif // MESH_MESH_H +#endif // MESH_MESH_H diff --git a/src/Mod/Mesh/App/MeshFeature.cpp b/src/Mod/Mesh/App/MeshFeature.cpp index c96a289ff8..e09b337304 100644 --- a/src/Mod/Mesh/App/MeshFeature.cpp +++ b/src/Mod/Mesh/App/MeshFeature.cpp @@ -39,20 +39,20 @@ PROPERTY_SOURCE(Mesh::Feature, App::GeoFeature) Feature::Feature() { - ADD_PROPERTY_TYPE(Mesh,(MeshObject()),0,App::Prop_Output,"The mesh kernel"); + ADD_PROPERTY_TYPE(Mesh, (MeshObject()), 0, App::Prop_Output, "The mesh kernel"); } -App::DocumentObjectExecReturn *Feature::execute() +App::DocumentObjectExecReturn* Feature::execute() { this->Mesh.touch(); return App::DocumentObject::StdReturn; } -PyObject *Feature::getPyObject() +PyObject* Feature::getPyObject() { - if(PythonObject.is(Py::_None())){ + if (PythonObject.is(Py::_None())) { // ref counter is set to 1 - PythonObject = Py::Object(new MeshFeaturePy(this),true); + PythonObject = Py::Object(new MeshFeaturePy(this), true); } return Py::new_reference_to(PythonObject); } @@ -68,8 +68,9 @@ void Feature::onChanged(const App::Property* prop) try { Base::Placement p; p.fromMatrix(this->Mesh.getTransform()); - if (p != this->Placement.getValue()) + if (p != this->Placement.getValue()) { this->Placement.setValue(p); + } } catch (const Base::ValueError&) { } @@ -86,27 +87,33 @@ void Feature::onChanged(const App::Property* prop) // --------------------------------------------------------- -namespace App { +namespace App +{ /// @cond DOXERR PROPERTY_SOURCE_TEMPLATE(Mesh::FeatureCustom, Mesh::Feature) /// @endcond // explicit template instantiation template class MeshExport FeatureCustomT; -} +} // namespace App // --------------------------------------------------------- -namespace App { +namespace App +{ /// @cond DOXERR PROPERTY_SOURCE_TEMPLATE(Mesh::FeaturePython, Mesh::Feature) -template<> const char* Mesh::FeaturePython::getViewProviderName() const { +template<> +const char* Mesh::FeaturePython::getViewProviderName() const +{ return "MeshGui::ViewProviderPython"; } -template<> PyObject* Mesh::FeaturePython::getPyObject() { +template<> +PyObject* Mesh::FeaturePython::getPyObject() +{ if (PythonObject.is(Py::_None())) { // ref counter is set to 1 - PythonObject = Py::Object(new FeaturePythonPyT(this),true); + PythonObject = Py::Object(new FeaturePythonPyT(this), true); } return Py::new_reference_to(PythonObject); } @@ -114,5 +121,4 @@ template<> PyObject* Mesh::FeaturePython::getPyObject() { // explicit template instantiation template class MeshExport FeaturePythonT; -} - +} // namespace App diff --git a/src/Mod/Mesh/App/MeshFeature.h b/src/Mod/Mesh/App/MeshFeature.h index 6653454039..8017e4271d 100644 --- a/src/Mod/Mesh/App/MeshFeature.h +++ b/src/Mod/Mesh/App/MeshFeature.h @@ -23,9 +23,9 @@ #ifndef MESH_FEATURE_H #define MESH_FEATURE_H -#include // must be before FeatureCustom.h #include #include +#include // must be before FeatureCustom.h #include "Core/MeshKernel.h" @@ -33,13 +33,15 @@ #include "MeshProperties.h" -namespace Base{ - class XMLReader; - class Writer; -} +namespace Base +{ +class XMLReader; +class Writer; +} // namespace Base -namespace MeshCore { - class MeshKernel; +namespace MeshCore +{ +class MeshKernel; } namespace Mesh @@ -52,7 +54,7 @@ class MeshFeaturePy; * This class holds a MeshKernel object. * \author Werner Mayer */ -class MeshExport Feature : public App::GeoFeature +class MeshExport Feature: public App::GeoFeature { PROPERTY_HEADER_WITH_OVERRIDE(Mesh::Feature); @@ -69,15 +71,17 @@ public: /** @name methods override Feature */ //@{ /// recalculate the Feature - App::DocumentObjectExecReturn *execute() override; + App::DocumentObjectExecReturn* execute() override; void onChanged(const App::Property* prop) override; //@} /// returns the type name of the ViewProvider - const char* getViewProviderName() const override { + const char* getViewProviderName() const override + { return "MeshGui::ViewProviderMeshFaceSet"; } - const App::PropertyComplexGeoData* getPropertyOfGeometry() const override { + const App::PropertyComplexGeoData* getPropertyOfGeometry() const override + { return &Mesh; } @@ -88,8 +92,7 @@ public: using FeatureCustom = App::FeatureCustomT; using FeaturePython = App::FeaturePythonT; -} //namespace Mesh - +} // namespace Mesh #endif diff --git a/src/Mod/Mesh/App/MeshFeaturePyImp.cpp b/src/Mod/Mesh/App/MeshFeaturePyImp.cpp index ad5025113f..8f02291db2 100644 --- a/src/Mod/Mesh/App/MeshFeaturePyImp.cpp +++ b/src/Mod/Mesh/App/MeshFeaturePyImp.cpp @@ -24,9 +24,11 @@ #include "MeshFeature.h" // inclusion of the generated files (generated out of MeshFeaturePy.xml) +// clang-format off #include #include #include +// clang-format on using namespace Mesh; @@ -41,51 +43,58 @@ std::string MeshFeaturePy::representation() const return str.str(); } -PyObject* MeshFeaturePy::countPoints(PyObject * /*args*/) +PyObject* MeshFeaturePy::countPoints(PyObject* /*args*/) { - return Py_BuildValue("i",getFeaturePtr()->Mesh.getValue().countPoints()); + return Py_BuildValue("i", getFeaturePtr()->Mesh.getValue().countPoints()); } -PyObject* MeshFeaturePy::countFacets(PyObject * /*args*/) +PyObject* MeshFeaturePy::countFacets(PyObject* /*args*/) { - return Py_BuildValue("i",getFeaturePtr()->Mesh.getValue().countFacets()); + return Py_BuildValue("i", getFeaturePtr()->Mesh.getValue().countFacets()); } -PyObject* MeshFeaturePy::harmonizeNormals(PyObject *args) +PyObject* MeshFeaturePy::harmonizeNormals(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { - Mesh::MeshObject *mesh = getFeaturePtr()->Mesh.startEditing(); + PY_TRY + { + Mesh::MeshObject* mesh = getFeaturePtr()->Mesh.startEditing(); mesh->harmonizeNormals(); getFeaturePtr()->Mesh.finishEditing(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshFeaturePy::smooth(PyObject *args) +PyObject* MeshFeaturePy::smooth(PyObject* args) { - int iter=1; - float d_max=FLOAT_MAX; - if (!PyArg_ParseTuple(args, "|if", &iter,&d_max)) + int iter = 1; + float d_max = FLOAT_MAX; + if (!PyArg_ParseTuple(args, "|if", &iter, &d_max)) { return nullptr; + } - PY_TRY { + PY_TRY + { Mesh::Feature* obj = getFeaturePtr(); MeshObject* kernel = obj->Mesh.startEditing(); kernel->smooth(iter, d_max); obj->Mesh.finishEditing(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshFeaturePy::removeNonManifolds(PyObject *args) +PyObject* MeshFeaturePy::removeNonManifolds(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } Mesh::Feature* obj = getFeaturePtr(); MeshObject* kernel = obj->Mesh.startEditing(); kernel->removeNonManifolds(); @@ -93,10 +102,11 @@ PyObject* MeshFeaturePy::removeNonManifolds(PyObject *args) Py_Return; } -PyObject* MeshFeaturePy::removeNonManifoldPoints(PyObject *args) +PyObject* MeshFeaturePy::removeNonManifoldPoints(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } Mesh::Feature* obj = getFeaturePtr(); MeshObject* kernel = obj->Mesh.startEditing(); kernel->removeNonManifoldPoints(); @@ -104,71 +114,84 @@ PyObject* MeshFeaturePy::removeNonManifoldPoints(PyObject *args) Py_Return; } -PyObject* MeshFeaturePy::fixIndices(PyObject *args) +PyObject* MeshFeaturePy::fixIndices(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { Mesh::Feature* obj = getFeaturePtr(); MeshObject* kernel = obj->Mesh.startEditing(); kernel->validateIndices(); obj->Mesh.finishEditing(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshFeaturePy::fixDegenerations(PyObject *args) +PyObject* MeshFeaturePy::fixDegenerations(PyObject* args) { float fEpsilon = MeshCore::MeshDefinitions::_fMinPointDistanceP2; - if (!PyArg_ParseTuple(args, "|f", &fEpsilon)) + if (!PyArg_ParseTuple(args, "|f", &fEpsilon)) { return nullptr; + } - PY_TRY { + PY_TRY + { Mesh::Feature* obj = getFeaturePtr(); MeshObject* kernel = obj->Mesh.startEditing(); kernel->validateDegenerations(fEpsilon); obj->Mesh.finishEditing(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshFeaturePy::removeDuplicatedFacets(PyObject *args) +PyObject* MeshFeaturePy::removeDuplicatedFacets(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { Mesh::Feature* obj = getFeaturePtr(); MeshObject* kernel = obj->Mesh.startEditing(); kernel->removeDuplicatedFacets(); obj->Mesh.finishEditing(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshFeaturePy::removeDuplicatedPoints(PyObject *args) +PyObject* MeshFeaturePy::removeDuplicatedPoints(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { Mesh::Feature* obj = getFeaturePtr(); MeshObject* kernel = obj->Mesh.startEditing(); kernel->removeDuplicatedPoints(); obj->Mesh.finishEditing(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshFeaturePy::fixSelfIntersections(PyObject *args) +PyObject* MeshFeaturePy::fixSelfIntersections(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } try { Mesh::Feature* obj = getFeaturePtr(); MeshObject* kernel = obj->Mesh.startEditing(); @@ -182,10 +205,11 @@ PyObject* MeshFeaturePy::fixSelfIntersections(PyObject *args) Py_Return; } -PyObject* MeshFeaturePy::removeFoldsOnSurface(PyObject *args) +PyObject* MeshFeaturePy::removeFoldsOnSurface(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } try { Mesh::Feature* obj = getFeaturePtr(); MeshObject* kernel = obj->Mesh.startEditing(); @@ -199,10 +223,11 @@ PyObject* MeshFeaturePy::removeFoldsOnSurface(PyObject *args) Py_Return; } -PyObject* MeshFeaturePy::removeInvalidPoints(PyObject *args) +PyObject* MeshFeaturePy::removeInvalidPoints(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } try { Mesh::Feature* obj = getFeaturePtr(); MeshObject* kernel = obj->Mesh.startEditing(); @@ -216,7 +241,7 @@ PyObject* MeshFeaturePy::removeInvalidPoints(PyObject *args) Py_Return; } -PyObject *MeshFeaturePy::getCustomAttributes(const char* /*attr*/) const +PyObject* MeshFeaturePy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } diff --git a/src/Mod/Mesh/App/MeshPoint.h b/src/Mod/Mesh/App/MeshPoint.h index a2d2372ede..5580237004 100644 --- a/src/Mod/Mesh/App/MeshPoint.h +++ b/src/Mod/Mesh/App/MeshPoint.h @@ -28,7 +28,7 @@ #include #ifndef MESH_GLOBAL_H -# include +#include #endif using Base::Vector3d; @@ -43,22 +43,29 @@ class MeshObject; * convenient access to the Mesh data structure. This class should not be used for * programming algorithms in C++. Use Mesh Core classes instead! */ -class MeshExport MeshPoint : public Vector3d +class MeshExport MeshPoint: public Vector3d { public: /// simple constructor - explicit MeshPoint(const Vector3d& vec = Vector3d(), const MeshObject* obj = nullptr, unsigned int index = UINT_MAX) - :Vector3d(vec),Index(index),Mesh(obj) + explicit MeshPoint(const Vector3d& vec = Vector3d(), + const MeshObject* obj = nullptr, + unsigned int index = UINT_MAX) + : Vector3d(vec) + , Index(index) + , Mesh(obj) {} - bool isBound() const {return Index != UINT_MAX;} + bool isBound() const + { + return Index != UINT_MAX; + } unsigned int Index; Base::Reference Mesh; }; -} // namespace Mesh +} // namespace Mesh -#endif // MESH_MESHPOINT_H +#endif // MESH_MESHPOINT_H diff --git a/src/Mod/Mesh/App/MeshPointPyImp.cpp b/src/Mod/Mesh/App/MeshPointPyImp.cpp index 4c0d2d2b88..966483c7f3 100644 --- a/src/Mod/Mesh/App/MeshPointPyImp.cpp +++ b/src/Mod/Mesh/App/MeshPointPyImp.cpp @@ -22,15 +22,17 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +#include #endif #include #include "Mesh.h" #include "MeshPoint.h" +// clang-format off #include "MeshPointPy.h" #include "MeshPointPy.cpp" +// clang-format on using namespace Mesh; @@ -45,7 +47,8 @@ std::string MeshPointPy::representation() const str << "MeshPoint ("; if (ptr->isBound()) { if (getMeshPointPtr()->Mesh->countPoints() <= getMeshPointPtr()->Index) { - str << vec.x << ", " << vec.y << ", " << vec.z << ", Idx=" << ptr->Index << " (Out of range)"; + str << vec.x << ", " << vec.y << ", " << vec.z << ", Idx=" << ptr->Index + << " (Out of range)"; } else { vec = getMeshPointPtr()->Mesh->getPoint(getMeshPointPtr()->Index); @@ -60,7 +63,7 @@ std::string MeshPointPy::representation() const return str.str(); } -PyObject *MeshPointPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper +PyObject* MeshPointPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper { // create a new instance of MeshPointPy and the Twin object return new MeshPointPy(new MeshPoint); @@ -69,18 +72,20 @@ PyObject *MeshPointPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // // constructor method int MeshPointPy::PyInit(PyObject* args, PyObject* /*kwds*/) { - double x=0.0,y=0.0,z=0.0; - if (!PyArg_ParseTuple(args, "|ddd", &x,&y,&z)) + double x = 0.0, y = 0.0, z = 0.0; + if (!PyArg_ParseTuple(args, "|ddd", &x, &y, &z)) { return -1; + } - getMeshPointPtr()->Set(x,y,z); + getMeshPointPtr()->Set(x, y, z); return 0; } -PyObject* MeshPointPy::unbound(PyObject *args) +PyObject* MeshPointPy::unbound(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } getMeshPointPtr()->Index = UINT_MAX; getMeshPointPtr()->Mesh = nullptr; Py_Return; @@ -88,7 +93,7 @@ PyObject* MeshPointPy::unbound(PyObject *args) Py::Long MeshPointPy::getIndex() const { - return Py::Long((long) getMeshPointPtr()->Index); + return Py::Long((long)getMeshPointPtr()->Index); } Py::Boolean MeshPointPy::getBound() const @@ -98,15 +103,19 @@ Py::Boolean MeshPointPy::getBound() const Py::Object MeshPointPy::getNormal() const { - if (!getMeshPointPtr()->isBound()) - throw Py::RuntimeError("This object is not bound to a mesh, so no topological operation is possible!"); - if (getMeshPointPtr()->Mesh->countPoints() <= getMeshPointPtr()->Index) + if (!getMeshPointPtr()->isBound()) { + throw Py::RuntimeError( + "This object is not bound to a mesh, so no topological operation is possible!"); + } + if (getMeshPointPtr()->Mesh->countPoints() <= getMeshPointPtr()->Index) { throw Py::IndexError("Index out of range"); + } - Base::Vector3d* v = new Base::Vector3d(getMeshPointPtr()->Mesh->getPointNormal(getMeshPointPtr()->Index)); + Base::Vector3d* v = + new Base::Vector3d(getMeshPointPtr()->Mesh->getPointNormal(getMeshPointPtr()->Index)); Base::VectorPy* normal = new Base::VectorPy(v); normal->setConst(); - return Py::Object(normal,true); + return Py::Object(normal, true); } Py::Object MeshPointPy::getVector() const @@ -115,7 +124,7 @@ Py::Object MeshPointPy::getVector() const Base::VectorPy* vec = new Base::VectorPy(*ptr); vec->setConst(); - return Py::Object(vec,true); + return Py::Object(vec, true); } Py::Float MeshPointPy::getx() const @@ -124,8 +133,9 @@ Py::Float MeshPointPy::getx() const double x = ptr->x; if (getMeshPointPtr()->isBound()) { - if (getMeshPointPtr()->Mesh->countPoints() > getMeshPointPtr()->Index) + if (getMeshPointPtr()->Mesh->countPoints() > getMeshPointPtr()->Index) { x = getMeshPointPtr()->Mesh->getPoint(getMeshPointPtr()->Index).x; + } } return Py::Float(x); @@ -137,8 +147,9 @@ Py::Float MeshPointPy::gety() const double y = ptr->y; if (getMeshPointPtr()->isBound()) { - if (getMeshPointPtr()->Mesh->countPoints() > getMeshPointPtr()->Index) + if (getMeshPointPtr()->Mesh->countPoints() > getMeshPointPtr()->Index) { y = getMeshPointPtr()->Mesh->getPoint(getMeshPointPtr()->Index).y; + } } return Py::Float(y); @@ -150,14 +161,15 @@ Py::Float MeshPointPy::getz() const double z = ptr->z; if (getMeshPointPtr()->isBound()) { - if (getMeshPointPtr()->Mesh->countPoints() > getMeshPointPtr()->Index) + if (getMeshPointPtr()->Mesh->countPoints() > getMeshPointPtr()->Index) { z = getMeshPointPtr()->Mesh->getPoint(getMeshPointPtr()->Index).z; + } } return Py::Float(z); } -PyObject *MeshPointPy::getCustomAttributes(const char* /*attr*/) const +PyObject* MeshPointPy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } diff --git a/src/Mod/Mesh/App/MeshProperties.cpp b/src/Mod/Mesh/App/MeshProperties.cpp index c353ed558c..761827f579 100644 --- a/src/Mod/Mesh/App/MeshProperties.cpp +++ b/src/Mod/Mesh/App/MeshProperties.cpp @@ -30,20 +30,20 @@ #include #include "Core/Iterator.h" -#include "Core/MeshKernel.h" #include "Core/MeshIO.h" +#include "Core/MeshKernel.h" -#include "MeshProperties.h" #include "Mesh.h" +#include "MeshProperties.h" #include "MeshPy.h" using namespace Mesh; TYPESYSTEM_SOURCE(Mesh::PropertyNormalList, App::PropertyLists) -TYPESYSTEM_SOURCE(Mesh::PropertyCurvatureList , App::PropertyLists) -TYPESYSTEM_SOURCE(Mesh::PropertyMaterial , App::Property) -TYPESYSTEM_SOURCE(Mesh::PropertyMeshKernel , App::PropertyComplexGeoData) +TYPESYSTEM_SOURCE(Mesh::PropertyCurvatureList, App::PropertyLists) +TYPESYSTEM_SOURCE(Mesh::PropertyMaterial, App::Property) +TYPESYSTEM_SOURCE(Mesh::PropertyMeshKernel, App::PropertyComplexGeoData) PropertyNormalList::PropertyNormalList() = default; @@ -61,7 +61,7 @@ void PropertyNormalList::setValue(const Base::Vector3f& lValue) { aboutToSetValue(); _lValueList.resize(1); - _lValueList[0]=lValue; + _lValueList[0] = lValue; hasSetValue(); } @@ -69,7 +69,7 @@ void PropertyNormalList::setValue(float x, float y, float z) { aboutToSetValue(); _lValueList.resize(1); - _lValueList[0].Set(x,y,z); + _lValueList[0].Set(x, y, z); hasSetValue(); } @@ -80,40 +80,41 @@ void PropertyNormalList::setValues(const std::vector& values) hasSetValue(); } -PyObject *PropertyNormalList::getPyObject() +PyObject* PropertyNormalList::getPyObject() { PyObject* list = PyList_New(getSize()); - for (int i = 0;i values; values.resize(nSize); - for (Py_ssize_t i=0; i(val.getValue()); } setValues(values); } else if (PyObject_TypeCheck(value, &(Base::VectorPy::Type))) { - Base::VectorPy *pcObject = static_cast(value); + Base::VectorPy* pcObject = static_cast(value); Base::Vector3d* val = pcObject->getVectorPtr(); setValue(Base::convertTo(*val)); } else if (PyTuple_Check(value) && PyTuple_Size(value) == 3) { App::PropertyVector val; - val.setPyObject( value ); + val.setPyObject(value); setValue(Base::convertTo(val.getValue())); } else { @@ -123,25 +124,26 @@ void PropertyNormalList::setPyObject(PyObject *value) } } -void PropertyNormalList::Save (Base::Writer &writer) const +void PropertyNormalList::Save(Base::Writer& writer) const { if (!writer.isForceXML()) { - writer.Stream() << writer.ind() << "" << std::endl; + writer.Stream() << writer.ind() << "" << std::endl; } } -void PropertyNormalList::Restore(Base::XMLReader &reader) +void PropertyNormalList::Restore(Base::XMLReader& reader) { reader.readElement("VectorList"); - std::string file (reader.getAttribute("file") ); + std::string file(reader.getAttribute("file")); if (!file.empty()) { // initiate a file read - reader.addFile(file.c_str(),this); + reader.addFile(file.c_str(), this); } } -void PropertyNormalList::SaveDocFile (Base::Writer &writer) const +void PropertyNormalList::SaveDocFile(Base::Writer& writer) const { Base::OutputStream str(writer.Stream()); uint32_t uCt = (uint32_t)getSize(); @@ -151,38 +153,38 @@ void PropertyNormalList::SaveDocFile (Base::Writer &writer) const } } -void PropertyNormalList::RestoreDocFile(Base::Reader &reader) +void PropertyNormalList::RestoreDocFile(Base::Reader& reader) { Base::InputStream str(reader); - uint32_t uCt=0; + uint32_t uCt = 0; str >> uCt; std::vector values(uCt); - for (auto & it : values) { + for (auto& it : values) { str >> it.x >> it.y >> it.z; } setValues(values); } -App::Property *PropertyNormalList::Copy() const +App::Property* PropertyNormalList::Copy() const { - PropertyNormalList *p= new PropertyNormalList(); + PropertyNormalList* p = new PropertyNormalList(); p->_lValueList = _lValueList; return p; } -void PropertyNormalList::Paste(const App::Property &from) +void PropertyNormalList::Paste(const App::Property& from) { aboutToSetValue(); _lValueList = dynamic_cast(from)._lValueList; hasSetValue(); } -unsigned int PropertyNormalList::getMemSize () const +unsigned int PropertyNormalList::getMemSize() const { return static_cast(_lValueList.size() * sizeof(Base::Vector3f)); } -void PropertyNormalList::transformGeometry(const Base::Matrix4D &mat) +void PropertyNormalList::transformGeometry(const Base::Matrix4D& mat) { // A normal vector is only a direction with unit length, so we only need to rotate it // (no translations or scaling) @@ -207,7 +209,7 @@ void PropertyNormalList::transformGeometry(const Base::Matrix4D &mat) aboutToSetValue(); // Rotate the normal vectors - for (int ii=0; ii& lValues) { aboutToSetValue(); - _lValueList=lValues; + _lValueList = lValues; hasSetValue(); } -std::vector PropertyCurvatureList::getCurvature( int mode ) const +std::vector PropertyCurvatureList::getCurvature(int mode) const { const std::vector& fCurvInfo = getValues(); std::vector fValues; @@ -241,47 +243,44 @@ std::vector PropertyCurvatureList::getCurvature( int mode ) const // Mean curvature if (mode == MeanCurvature) { - for (const auto & it : fCurvInfo) - { - fValues.push_back( 0.5f*(it.fMaxCurvature+it.fMinCurvature) ); + for (const auto& it : fCurvInfo) { + fValues.push_back(0.5f * (it.fMaxCurvature + it.fMinCurvature)); } } // Gaussian curvature else if (mode == GaussCurvature) { - for (const auto & it : fCurvInfo) - { - fValues.push_back( it.fMaxCurvature * it.fMinCurvature ); + for (const auto& it : fCurvInfo) { + fValues.push_back(it.fMaxCurvature * it.fMinCurvature); } } // Maximum curvature else if (mode == MaxCurvature) { - for (const auto & it : fCurvInfo) - { - fValues.push_back( it.fMaxCurvature ); + for (const auto& it : fCurvInfo) { + fValues.push_back(it.fMaxCurvature); } } // Minimum curvature else if (mode == MinCurvature) { - for (const auto & it : fCurvInfo) - { - fValues.push_back( it.fMinCurvature ); + for (const auto& it : fCurvInfo) { + fValues.push_back(it.fMinCurvature); } } // Absolute curvature else if (mode == AbsCurvature) { - for (const auto & it : fCurvInfo) - { - if ( fabs(it.fMaxCurvature) > fabs(it.fMinCurvature) ) - fValues.push_back( it.fMaxCurvature ); - else - fValues.push_back( it.fMinCurvature ); + for (const auto& it : fCurvInfo) { + if (fabs(it.fMaxCurvature) > fabs(it.fMinCurvature)) { + fValues.push_back(it.fMaxCurvature); + } + else { + fValues.push_back(it.fMinCurvature); + } } } return fValues; } -void PropertyCurvatureList::transformGeometry(const Base::Matrix4D &mat) +void PropertyCurvatureList::transformGeometry(const Base::Matrix4D& mat) { // The principal direction is only a vector with unit length, so we only need to rotate it // (no translations or scaling) @@ -306,8 +305,7 @@ void PropertyCurvatureList::transformGeometry(const Base::Matrix4D &mat) aboutToSetValue(); // Rotate the principal directions - for (int ii=0; ii" << std::endl; + writer.Stream() << writer.ind() << "" << std::endl; } } -void PropertyCurvatureList::Restore(Base::XMLReader &reader) +void PropertyCurvatureList::Restore(Base::XMLReader& reader) { reader.readElement("CurvatureList"); - std::string file (reader.getAttribute("file") ); + std::string file(reader.getAttribute("file")); if (!file.empty()) { // initiate a file read - reader.addFile(file.c_str(),this); + reader.addFile(file.c_str(), this); } } -void PropertyCurvatureList::SaveDocFile (Base::Writer &writer) const +void PropertyCurvatureList::SaveDocFile(Base::Writer& writer) const { Base::OutputStream str(writer.Stream()); uint32_t uCt = (uint32_t)getSize(); str << uCt; - for (const auto & it : _lValueList) { + for (const auto& it : _lValueList) { str << it.fMaxCurvature << it.fMinCurvature; str << it.cMaxCurvDir.x << it.cMaxCurvDir.y << it.cMaxCurvDir.z; str << it.cMinCurvDir.x << it.cMinCurvDir.y << it.cMinCurvDir.z; } } -void PropertyCurvatureList::RestoreDocFile(Base::Reader &reader) +void PropertyCurvatureList::RestoreDocFile(Base::Reader& reader) { Base::InputStream str(reader); - uint32_t uCt=0; + uint32_t uCt = 0; str >> uCt; std::vector values(uCt); - for (auto & it : values) { + for (auto& it : values) { str >> it.fMaxCurvature >> it.fMinCurvature; str >> it.cMaxCurvDir.x >> it.cMaxCurvDir.y >> it.cMaxCurvDir.z; str >> it.cMinCurvDir.x >> it.cMinCurvDir.y >> it.cMinCurvDir.z; @@ -366,7 +364,7 @@ void PropertyCurvatureList::RestoreDocFile(Base::Reader &reader) PyObject* PropertyCurvatureList::getPyObject() { Py::List list; - for (const auto & it : _lValueList) { + for (const auto& it : _lValueList) { Py::Tuple tuple(4); tuple.setItem(0, Py::Float(it.fMaxCurvature)); tuple.setItem(1, Py::Float(it.fMinCurvature)); @@ -391,14 +389,14 @@ void PropertyCurvatureList::setPyObject(PyObject* /*value*/) throw Base::AttributeError(std::string("This attribute is read-only")); } -App::Property *PropertyCurvatureList::Copy() const +App::Property* PropertyCurvatureList::Copy() const { - PropertyCurvatureList *p= new PropertyCurvatureList(); + PropertyCurvatureList* p = new PropertyCurvatureList(); p->_lValueList = _lValueList; return p; } -void PropertyCurvatureList::Paste(const App::Property &from) +void PropertyCurvatureList::Paste(const App::Property& from) { aboutToSetValue(); _lValueList = dynamic_cast(from)._lValueList; @@ -508,9 +506,7 @@ PyObject* PropertyMaterial::getPyObject() auto getColorList = [](const std::vector& color) { Py::List list; for (const auto& it : color) { - list.append(Py::TupleN(Py::Float(it.r), - Py::Float(it.g), - Py::Float(it.b))); + list.append(Py::TupleN(Py::Float(it.r), Py::Float(it.g), Py::Float(it.b))); } return list; }; @@ -593,8 +589,8 @@ void PropertyMaterial::setPyObject(PyObject* obj) void PropertyMaterial::Save(Base::Writer& writer) const { if (!writer.isForceXML()) { - writer.Stream() << writer.ind() << "" << std::endl; + writer.Stream() << writer.ind() << "" << std::endl; } } @@ -611,7 +607,7 @@ void PropertyMaterial::Restore(Base::XMLReader& reader) } } -void PropertyMaterial::SaveDocFile(Base::Writer &writer) const +void PropertyMaterial::SaveDocFile(Base::Writer& writer) const { Base::OutputStream str(writer.Stream()); auto saveColor = [&str](const std::vector& color) { @@ -641,7 +637,7 @@ void PropertyMaterial::SaveDocFile(Base::Writer &writer) const saveFloat(_material.transparency); } -void PropertyMaterial::RestoreDocFile(Base::Reader &reader) +void PropertyMaterial::RestoreDocFile(Base::Reader& reader) { Base::InputStream str(reader); auto restoreColor = [&str](std::vector& color) { @@ -649,7 +645,7 @@ void PropertyMaterial::RestoreDocFile(Base::Reader &reader) str >> count; color.resize(count); for (auto& it : color) { - uint32_t value; // must be 32 bit long + uint32_t value; // must be 32 bit long str >> value; it.setPackedValue(value); } @@ -689,7 +685,7 @@ const char* PropertyMaterial::getEditorName() const App::Property* PropertyMaterial::Copy() const { - PropertyMaterial *prop = new PropertyMaterial(); + PropertyMaterial* prop = new PropertyMaterial(); prop->_material = _material; return prop; } @@ -704,20 +700,19 @@ void PropertyMaterial::Paste(const Property& from) unsigned int PropertyMaterial::getMemSize() const { - auto size = (_material.ambientColor.size() + - _material.diffuseColor.size() + - _material.emissiveColor.size() + - _material.specularColor.size()) * sizeof(App::Color) + - (_material.shininess.size() + - _material.transparency.size()) * sizeof(float) + - _material.library.size() + sizeof(_material); + auto size = (_material.ambientColor.size() + _material.diffuseColor.size() + + _material.emissiveColor.size() + _material.specularColor.size()) + * sizeof(App::Color) + + (_material.shininess.size() + _material.transparency.size()) * sizeof(float) + + _material.library.size() + sizeof(_material); return static_cast(size); } bool PropertyMaterial::isSame(const App::Property& other) const { - if (&other == this) + if (&other == this) { return true; + } return getTypeId() == other.getTypeId() && getValue() == static_cast(&other)->getValue(); } @@ -725,7 +720,7 @@ bool PropertyMaterial::isSame(const App::Property& other) const // ---------------------------------------------------------------------------- PropertyMeshKernel::PropertyMeshKernel() - : _meshObject(new MeshObject()) + : _meshObject(new MeshObject()) { // Note: Normally this property is a member of a document object, i.e. the setValue() // method gets called in the constructor of a subclass of DocumentObject, e.g. Mesh::Feature. @@ -781,12 +776,12 @@ void PropertyMeshKernel::swapMesh(MeshCore::MeshKernel& mesh) hasSetValue(); } -const MeshObject& PropertyMeshKernel::getValue()const +const MeshObject& PropertyMeshKernel::getValue() const { return *_meshObject; } -const MeshObject* PropertyMeshKernel::getValuePtr()const +const MeshObject* PropertyMeshKernel::getValuePtr() const { return static_cast(_meshObject); } @@ -801,7 +796,7 @@ Base::BoundBox3d PropertyMeshKernel::getBoundingBox() const return _meshObject->getBoundBox(); } -unsigned int PropertyMeshKernel::getMemSize () const +unsigned int PropertyMeshKernel::getMemSize() const { unsigned int size = 0; size += _meshObject->getMemSize(); @@ -820,19 +815,21 @@ void PropertyMeshKernel::finishEditing() hasSetValue(); } -void PropertyMeshKernel::transformGeometry(const Base::Matrix4D &rclMat) +void PropertyMeshKernel::transformGeometry(const Base::Matrix4D& rclMat) { aboutToSetValue(); _meshObject->transformGeometry(rclMat); hasSetValue(); } -void PropertyMeshKernel::setPointIndices(const std::vector >& inds) +void PropertyMeshKernel::setPointIndices( + const std::vector>& inds) { aboutToSetValue(); MeshCore::MeshKernel& kernel = _meshObject->getKernel(); - for (const auto & it : inds) + for (const auto& it : inds) { kernel.SetPoint(it.first, it.second); + } hasSetValue(); } @@ -846,11 +843,13 @@ Base::Matrix4D PropertyMeshKernel::getTransform() const return _meshObject->getTransform(); } -PyObject *PropertyMeshKernel::getPyObject() +PyObject* PropertyMeshKernel::getPyObject() { if (!meshPyObject) { - meshPyObject = new MeshPy(&*_meshObject); // Lgtm[cpp/resource-not-released-in-destructor] ** Not destroyed in this class because it is reference-counted and destroyed elsewhere - meshPyObject->setConst(); // set immutable + meshPyObject = new MeshPy( + &*_meshObject); // Lgtm[cpp/resource-not-released-in-destructor] ** Not destroyed in + // this class because it is reference-counted and destroyed elsewhere + meshPyObject->setConst(); // set immutable meshPyObject->parentProperty = this; } @@ -858,7 +857,7 @@ PyObject *PropertyMeshKernel::getPyObject() return meshPyObject; } -void PropertyMeshKernel::setPyObject(PyObject *value) +void PropertyMeshKernel::setPyObject(PyObject* value) { if (PyObject_TypeCheck(value, &(MeshPy::Type))) { MeshPy* mesh = static_cast(value); @@ -881,7 +880,7 @@ void PropertyMeshKernel::setPyObject(PyObject *value) } } -void PropertyMeshKernel::Save (Base::Writer &writer) const +void PropertyMeshKernel::Save(Base::Writer& writer) const { if (writer.isForceXML()) { writer.Stream() << writer.ind() << "" << std::endl; @@ -889,15 +888,15 @@ void PropertyMeshKernel::Save (Base::Writer &writer) const saver.SaveXML(writer); } else { - writer.Stream() << writer.ind() << "" << std::endl; + writer.Stream() << writer.ind() << "" << std::endl; } } -void PropertyMeshKernel::Restore(Base::XMLReader &reader) +void PropertyMeshKernel::Restore(Base::XMLReader& reader) { reader.readElement("Mesh"); - std::string file (reader.getAttribute("file") ); + std::string file(reader.getAttribute("file")); if (file.empty()) { // read XML @@ -916,31 +915,31 @@ void PropertyMeshKernel::Restore(Base::XMLReader &reader) } else { // initiate a file read - reader.addFile(file.c_str(),this); + reader.addFile(file.c_str(), this); } } -void PropertyMeshKernel::SaveDocFile (Base::Writer &writer) const +void PropertyMeshKernel::SaveDocFile(Base::Writer& writer) const { _meshObject->save(writer.Stream()); } -void PropertyMeshKernel::RestoreDocFile(Base::Reader &reader) +void PropertyMeshKernel::RestoreDocFile(Base::Reader& reader) { aboutToSetValue(); _meshObject->load(reader); hasSetValue(); } -App::Property *PropertyMeshKernel::Copy() const +App::Property* PropertyMeshKernel::Copy() const { // Note: Copy the content, do NOT reference the same mesh object - PropertyMeshKernel *prop = new PropertyMeshKernel(); + PropertyMeshKernel* prop = new PropertyMeshKernel(); *(prop->_meshObject) = *(this->_meshObject); return prop; } -void PropertyMeshKernel::Paste(const App::Property &from) +void PropertyMeshKernel::Paste(const App::Property& from) { // Note: Copy the content, do NOT reference the same mesh object aboutToSetValue(); diff --git a/src/Mod/Mesh/App/MeshProperties.h b/src/Mod/Mesh/App/MeshProperties.h index 47c14c185a..123312e8e7 100644 --- a/src/Mod/Mesh/App/MeshProperties.h +++ b/src/Mod/Mesh/App/MeshProperties.h @@ -60,35 +60,38 @@ public: void setValue(const Base::Vector3f&); void setValue(float x, float y, float z); - const Base::Vector3f& operator[] (const int idx) const { + const Base::Vector3f& operator[](const int idx) const + { return _lValueList[idx]; } - void set1Value (const int idx, const Base::Vector3f& value) { + void set1Value(const int idx, const Base::Vector3f& value) + { _lValueList[idx] = value; } - void setValues (const std::vector& values); + void setValues(const std::vector& values); - const std::vector &getValues() const { + const std::vector& getValues() const + { return _lValueList; } - PyObject *getPyObject() override; - void setPyObject(PyObject *) override; + PyObject* getPyObject() override; + void setPyObject(PyObject*) override; - void Save (Base::Writer &writer) const override; - void Restore(Base::XMLReader &reader) override; + void Save(Base::Writer& writer) const override; + void Restore(Base::XMLReader& reader) override; - void SaveDocFile (Base::Writer &writer) const override; - void RestoreDocFile(Base::Reader &reader) override; + void SaveDocFile(Base::Writer& writer) const override; + void RestoreDocFile(Base::Reader& reader) override; - App::Property *Copy() const override; - void Paste(const App::Property &from) override; + App::Property* Copy() const override; + void Paste(const App::Property& from) override; - unsigned int getMemSize () const override; + unsigned int getMemSize() const override; - void transformGeometry(const Base::Matrix4D &rclMat); + void transformGeometry(const Base::Matrix4D& rclMat); private: std::vector _lValueList; @@ -109,51 +112,64 @@ class MeshExport PropertyCurvatureList: public App::PropertyLists TYPESYSTEM_HEADER_WITH_OVERRIDE(); public: - enum { - MeanCurvature = 0, /**< Mean curvature */ - GaussCurvature = 1, /**< Gaussian curvature */ - MaxCurvature = 2, /**< Maximum curvature */ - MinCurvature = 3, /**< Minimum curvature */ - AbsCurvature = 4 /**< Absolute curvature */ + enum + { + MeanCurvature = 0, /**< Mean curvature */ + GaussCurvature = 1, /**< Gaussian curvature */ + MaxCurvature = 2, /**< Maximum curvature */ + MinCurvature = 3, /**< Minimum curvature */ + AbsCurvature = 4 /**< Absolute curvature */ }; public: PropertyCurvatureList(); - void setSize(int newSize) override{_lValueList.resize(newSize);} - int getSize() const override {return _lValueList.size();} - std::vector getCurvature( int tMode) const; + void setSize(int newSize) override + { + _lValueList.resize(newSize); + } + int getSize() const override + { + return _lValueList.size(); + } + std::vector getCurvature(int tMode) const; void setValue(const CurvatureInfo&); void setValues(const std::vector&); /// index operator - const CurvatureInfo& operator[] (const int idx) const { + const CurvatureInfo& operator[](const int idx) const + { return _lValueList[idx]; } - void set1Value (const int idx, const CurvatureInfo& value) { + void set1Value(const int idx, const CurvatureInfo& value) + { _lValueList[idx] = value; } - const std::vector &getValues() const { + const std::vector& getValues() const + { return _lValueList; } - void transformGeometry(const Base::Matrix4D &rclMat); + void transformGeometry(const Base::Matrix4D& rclMat); - void Save (Base::Writer &writer) const override; - void Restore(Base::XMLReader &reader) override; + void Save(Base::Writer& writer) const override; + void Restore(Base::XMLReader& reader) override; - void SaveDocFile (Base::Writer &writer) const override; - void RestoreDocFile(Base::Reader &reader) override; + void SaveDocFile(Base::Writer& writer) const override; + void RestoreDocFile(Base::Reader& reader) override; /** @name Python interface */ //@{ PyObject* getPyObject() override; - void setPyObject(PyObject *value) override; + void setPyObject(PyObject* value) override; //@} - App::Property *Copy() const override; - void Paste(const App::Property &from) override; + App::Property* Copy() const override; + void Paste(const App::Property& from) override; - unsigned int getMemSize () const override{return _lValueList.size() * sizeof(CurvatureInfo);} + unsigned int getMemSize() const override + { + return _lValueList.size() * sizeof(CurvatureInfo); + } private: std::vector _lValueList; @@ -161,7 +177,7 @@ private: /** Mesh material properties */ -class MeshExport PropertyMaterial : public App::Property +class MeshExport PropertyMaterial: public App::Property { TYPESYSTEM_HEADER_WITH_OVERRIDE(); @@ -170,7 +186,7 @@ public: /** Sets the property */ - void setValue(const MeshCore::Material &mat); + void setValue(const MeshCore::Material& mat); void setAmbientColor(const std::vector& col); void setDiffuseColor(const std::vector& col); void setSpecularColor(const std::vector& col); @@ -191,7 +207,7 @@ public: PyObject* getPyObject() override; void setPyObject(PyObject*) override; - void Save (Base::Writer& writer) const override; + void Save(Base::Writer& writer) const override; void Restore(Base::XMLReader& reader) override; void SaveDocFile(Base::Writer& writer) const override; @@ -212,7 +228,7 @@ private: /** The mesh kernel property class. * @author Werner Mayer */ -class MeshExport PropertyMeshKernel : public App::PropertyComplexGeoData +class MeshExport PropertyMeshKernel: public App::PropertyComplexGeoData { TYPESYSTEM_HEADER_WITH_OVERRIDE(); @@ -242,9 +258,9 @@ public: /** Returns a the attached mesh object by reference. It cannot be modified * from outside. */ - const MeshObject &getValue() const; - const MeshObject *getValuePtr() const; - unsigned int getMemSize () const override; + const MeshObject& getValue() const; + const MeshObject* getValuePtr() const; + unsigned int getMemSize() const override; //@} /** @name Getting basic geometric entities */ @@ -259,8 +275,8 @@ public: MeshObject* startEditing(); void finishEditing(); /// Transform the real mesh data - void transformGeometry(const Base::Matrix4D &rclMat) override; - void setPointIndices( const std::vector >& ); + void transformGeometry(const Base::Matrix4D& rclMat) override; + void setPointIndices(const std::vector>&); void setTransform(const Base::Matrix4D& rclTrf) override; Base::Matrix4D getTransform() const override; //@} @@ -277,30 +293,31 @@ public: * wrapper for the mesh object or simply a list of triangles, i.e. a list * of lists of three floats. */ - void setPyObject(PyObject *value) override; + void setPyObject(PyObject* value) override; //@} - const char* getEditorName() const override { + const char* getEditorName() const override + { return "MeshGui::PropertyMeshKernelItem"; } /** @name Save/restore */ //@{ - void Save (Base::Writer &writer) const override; - void Restore(Base::XMLReader &reader) override; + void Save(Base::Writer& writer) const override; + void Restore(Base::XMLReader& reader) override; - void SaveDocFile (Base::Writer &writer) const override; - void RestoreDocFile(Base::Reader &reader) override; + void SaveDocFile(Base::Writer& writer) const override; + void RestoreDocFile(Base::Reader& reader) override; - App::Property *Copy() const override; - void Paste(const App::Property &from) override; + App::Property* Copy() const override; + void Paste(const App::Property& from) override; //@} private: Base::Reference _meshObject; - MeshPy* meshPyObject{nullptr}; + MeshPy* meshPyObject {nullptr}; }; -} // namespace Mesh +} // namespace Mesh -#endif // MESH_MESHPROPERTIES_H +#endif // MESH_MESHPROPERTIES_H diff --git a/src/Mod/Mesh/App/MeshPyImp.cpp b/src/Mod/Mesh/App/MeshPyImp.cpp index aefab5aba5..7fb3bfdae0 100644 --- a/src/Mod/Mesh/App/MeshPyImp.cpp +++ b/src/Mod/Mesh/App/MeshPyImp.cpp @@ -37,69 +37,87 @@ #include "Core/Smoothing.h" #include "Core/Triangulation.h" +// clang-format off #include "Mesh.h" #include "MeshPy.h" #include "MeshPointPy.h" #include "FacetPy.h" #include "MeshPy.cpp" #include "MeshProperties.h" +// clang-format on using namespace Mesh; -struct MeshPropertyLock { - explicit MeshPropertyLock(PropertyMeshKernel* p) : prop(p) - { if (prop) prop->startEditing(); } +struct MeshPropertyLock +{ + explicit MeshPropertyLock(PropertyMeshKernel* p) + : prop(p) + { + if (prop) { + prop->startEditing(); + } + } ~MeshPropertyLock() - { if (prop) prop->finishEditing(); } + { + if (prop) { + prop->finishEditing(); + } + } + private: PropertyMeshKernel* prop; }; int MeshPy::PyInit(PyObject* args, PyObject*) { - PyObject *pcObj=nullptr; - if (!PyArg_ParseTuple(args, "|O", &pcObj)) + PyObject* pcObj = nullptr; + if (!PyArg_ParseTuple(args, "|O", &pcObj)) { return -1; + } try { this->parentProperty = nullptr; // if no mesh is given - if (!pcObj) + if (!pcObj) { return 0; + } if (PyObject_TypeCheck(pcObj, &(MeshPy::Type))) { - getMeshObjectPtr()->operator = (*static_cast(pcObj)->getMeshObjectPtr()); + getMeshObjectPtr()->operator=(*static_cast(pcObj)->getMeshObjectPtr()); } else if (PyList_Check(pcObj)) { PyObject* ret = addFacets(args); bool ok = (ret != nullptr); Py_XDECREF(ret); - if (!ok) + if (!ok) { return -1; + } } else if (PyTuple_Check(pcObj)) { PyObject* ret = addFacets(args); bool ok = (ret != nullptr); Py_XDECREF(ret); - if (!ok) + if (!ok) { return -1; + } } else if (PyUnicode_Check(pcObj)) { getMeshObjectPtr()->load(PyUnicode_AsUTF8(pcObj)); } else { - PyErr_Format(PyExc_TypeError, "Cannot create a mesh out of a '%s'", - pcObj->ob_type->tp_name); + PyErr_Format(PyExc_TypeError, + "Cannot create a mesh out of a '%s'", + pcObj->ob_type->tp_name); return -1; } } - catch (const Base::Exception &e) { + catch (const Base::Exception& e) { e.setPyException(); return -1; } - catch (const std::exception &e) { - PyErr_SetString(Base::PyExc_FC_GeneralError,e.what()); + catch (const std::exception& e) { + PyErr_SetString(Base::PyExc_FC_GeneralError, e.what()); return -1; } catch (const Py::Exception&) { @@ -115,24 +133,25 @@ std::string MeshPy::representation() const return getMeshObjectPtr()->representation(); } -PyObject *MeshPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper +PyObject* MeshPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper { // create a new instance of MeshPy and the Twin object return new MeshPy(new MeshObject); } -PyObject* MeshPy::copy(PyObject *args) +PyObject* MeshPy::copy(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } return new MeshPy(new MeshObject(*getMeshObjectPtr())); } -PyObject* MeshPy::read(PyObject *args, PyObject *kwds) +PyObject* MeshPy::read(PyObject* args, PyObject* kwds) { char* Name; - static const std::array keywords_path {"Filename",nullptr}; + static const std::array keywords_path {"Filename", nullptr}; if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "et", keywords_path, "utf-8", &Name)) { getMeshObjectPtr()->load(Name); PyMem_Free(Name); @@ -143,28 +162,28 @@ PyObject* MeshPy::read(PyObject *args, PyObject *kwds) MeshCore::MeshIO::Format format = MeshCore::MeshIO::Undefined; std::map ext; - ext["BMS" ] = MeshCore::MeshIO::BMS; - ext["STL" ] = MeshCore::MeshIO::BSTL; - ext["AST" ] = MeshCore::MeshIO::ASTL; - ext["OBJ" ] = MeshCore::MeshIO::OBJ; - ext["SMF" ] = MeshCore::MeshIO::SMF; - ext["OFF" ] = MeshCore::MeshIO::OFF; - ext["IV" ] = MeshCore::MeshIO::IV; - ext["X3D" ] = MeshCore::MeshIO::X3D; + ext["BMS"] = MeshCore::MeshIO::BMS; + ext["STL"] = MeshCore::MeshIO::BSTL; + ext["AST"] = MeshCore::MeshIO::ASTL; + ext["OBJ"] = MeshCore::MeshIO::OBJ; + ext["SMF"] = MeshCore::MeshIO::SMF; + ext["OFF"] = MeshCore::MeshIO::OFF; + ext["IV"] = MeshCore::MeshIO::IV; + ext["X3D"] = MeshCore::MeshIO::X3D; ext["X3DZ"] = MeshCore::MeshIO::X3DZ; ext["VRML"] = MeshCore::MeshIO::VRML; - ext["WRL" ] = MeshCore::MeshIO::VRML; - ext["WRZ" ] = MeshCore::MeshIO::WRZ; - ext["NAS" ] = MeshCore::MeshIO::NAS; - ext["BDF" ] = MeshCore::MeshIO::NAS; - ext["PLY" ] = MeshCore::MeshIO::PLY; + ext["WRL"] = MeshCore::MeshIO::VRML; + ext["WRZ"] = MeshCore::MeshIO::WRZ; + ext["NAS"] = MeshCore::MeshIO::NAS; + ext["BDF"] = MeshCore::MeshIO::NAS; + ext["PLY"] = MeshCore::MeshIO::PLY; ext["APLY"] = MeshCore::MeshIO::APLY; - ext["PY" ] = MeshCore::MeshIO::PY; + ext["PY"] = MeshCore::MeshIO::PY; PyObject* input; char* Ext; - static const std::array keywords_stream {"Stream", "Format", nullptr}; - if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "Os",keywords_stream, &input, &Ext)) { + static const std::array keywords_stream {"Stream", "Format", nullptr}; + if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "Os", keywords_stream, &input, &Ext)) { std::string fmt(Ext); boost::to_upper(fmt); if (ext.find(fmt) != ext.end()) { @@ -184,41 +203,52 @@ PyObject* MeshPy::read(PyObject *args, PyObject *kwds) return nullptr; } -PyObject* MeshPy::write(PyObject *args, PyObject *kwds) +PyObject* MeshPy::write(PyObject* args, PyObject* kwds) { char* Name; - char* Ext=nullptr; - char* ObjName=nullptr; - PyObject* List=nullptr; + char* Ext = nullptr; + char* ObjName = nullptr; + PyObject* List = nullptr; MeshCore::MeshIO::Format format = MeshCore::MeshIO::Undefined; std::map ext; - ext["BMS" ] = MeshCore::MeshIO::BMS; - ext["STL" ] = MeshCore::MeshIO::BSTL; - ext["AST" ] = MeshCore::MeshIO::ASTL; - ext["OBJ" ] = MeshCore::MeshIO::OBJ; - ext["SMF" ] = MeshCore::MeshIO::SMF; - ext["OFF" ] = MeshCore::MeshIO::OFF; - ext["IDTF" ] = MeshCore::MeshIO::IDTF; - ext["MGL" ] = MeshCore::MeshIO::MGL; - ext["IV" ] = MeshCore::MeshIO::IV; - ext["X3D" ] = MeshCore::MeshIO::X3D; - ext["X3DZ" ] = MeshCore::MeshIO::X3DZ; + ext["BMS"] = MeshCore::MeshIO::BMS; + ext["STL"] = MeshCore::MeshIO::BSTL; + ext["AST"] = MeshCore::MeshIO::ASTL; + ext["OBJ"] = MeshCore::MeshIO::OBJ; + ext["SMF"] = MeshCore::MeshIO::SMF; + ext["OFF"] = MeshCore::MeshIO::OFF; + ext["IDTF"] = MeshCore::MeshIO::IDTF; + ext["MGL"] = MeshCore::MeshIO::MGL; + ext["IV"] = MeshCore::MeshIO::IV; + ext["X3D"] = MeshCore::MeshIO::X3D; + ext["X3DZ"] = MeshCore::MeshIO::X3DZ; ext["X3DOM"] = MeshCore::MeshIO::X3DOM; - ext["VRML" ] = MeshCore::MeshIO::VRML; - ext["WRL" ] = MeshCore::MeshIO::VRML; - ext["WRZ" ] = MeshCore::MeshIO::WRZ; - ext["NAS" ] = MeshCore::MeshIO::NAS; - ext["BDF" ] = MeshCore::MeshIO::NAS; - ext["PLY" ] = MeshCore::MeshIO::PLY; - ext["APLY" ] = MeshCore::MeshIO::APLY; - ext["PY" ] = MeshCore::MeshIO::PY; - ext["ASY" ] = MeshCore::MeshIO::ASY; - ext["3MF" ] = MeshCore::MeshIO::ThreeMF; + ext["VRML"] = MeshCore::MeshIO::VRML; + ext["WRL"] = MeshCore::MeshIO::VRML; + ext["WRZ"] = MeshCore::MeshIO::WRZ; + ext["NAS"] = MeshCore::MeshIO::NAS; + ext["BDF"] = MeshCore::MeshIO::NAS; + ext["PLY"] = MeshCore::MeshIO::PLY; + ext["APLY"] = MeshCore::MeshIO::APLY; + ext["PY"] = MeshCore::MeshIO::PY; + ext["ASY"] = MeshCore::MeshIO::ASY; + ext["3MF"] = MeshCore::MeshIO::ThreeMF; - static const std::array keywords_path {"Filename","Format","Name","Material",nullptr}; - if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "et|ssO", keywords_path, "utf-8", - &Name, &Ext, &ObjName, &List)) { + static const std::array keywords_path {"Filename", + "Format", + "Name", + "Material", + nullptr}; + if (Base::Wrapped_ParseTupleAndKeywords(args, + kwds, + "et|ssO", + keywords_path, + "utf-8", + &Name, + &Ext, + &ObjName, + &List)) { if (Ext) { std::string fmt(Ext); boost::to_upper(fmt); @@ -235,15 +265,18 @@ PyObject* MeshPy::write(PyObject *args, PyObject *kwds) float r = (float)Py::Float(t.getItem(0)); float g = (float)Py::Float(t.getItem(1)); float b = (float)Py::Float(t.getItem(2)); - mat.diffuseColor.emplace_back(r,g,b); + mat.diffuseColor.emplace_back(r, g, b); } - if (mat.diffuseColor.size() == getMeshObjectPtr()->countPoints()) + if (mat.diffuseColor.size() == getMeshObjectPtr()->countPoints()) { mat.binding = MeshCore::MeshIO::PER_VERTEX; - else if (mat.diffuseColor.size() == getMeshObjectPtr()->countFacets()) + } + else if (mat.diffuseColor.size() == getMeshObjectPtr()->countFacets()) { mat.binding = MeshCore::MeshIO::PER_FACE; - else + } + else { mat.binding = MeshCore::MeshIO::OVERALL; + } getMeshObjectPtr()->save(Name, format, &mat, ObjName); } else { @@ -256,10 +289,20 @@ PyObject* MeshPy::write(PyObject *args, PyObject *kwds) PyErr_Clear(); - static const std::array keywords_stream {"Stream", "Format", "Name", "Material", nullptr}; + static const std::array keywords_stream {"Stream", + "Format", + "Name", + "Material", + nullptr}; PyObject* input; - if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "Os|sO", keywords_stream, - &input, &Ext, &ObjName, &List)) { + if (Base::Wrapped_ParseTupleAndKeywords(args, + kwds, + "Os|sO", + keywords_stream, + &input, + &Ext, + &ObjName, + &List)) { std::string fmt(Ext); boost::to_upper(fmt); if (ext.find(fmt) != ext.end()) { @@ -275,15 +318,18 @@ PyObject* MeshPy::write(PyObject *args, PyObject *kwds) float r = (float)Py::Float(t.getItem(0)); float g = (float)Py::Float(t.getItem(1)); float b = (float)Py::Float(t.getItem(2)); - mat->diffuseColor.emplace_back(r,g,b); + mat->diffuseColor.emplace_back(r, g, b); } - if (mat->diffuseColor.size() == getMeshObjectPtr()->countPoints()) + if (mat->diffuseColor.size() == getMeshObjectPtr()->countPoints()) { mat->binding = MeshCore::MeshIO::PER_VERTEX; - else if (mat->diffuseColor.size() == getMeshObjectPtr()->countFacets()) + } + else if (mat->diffuseColor.size() == getMeshObjectPtr()->countFacets()) { mat->binding = MeshCore::MeshIO::PER_FACE; - else + } + else { mat->binding = MeshCore::MeshIO::OVERALL; + } } // write mesh @@ -299,11 +345,12 @@ PyObject* MeshPy::write(PyObject *args, PyObject *kwds) return nullptr; } -PyObject* MeshPy::writeInventor(PyObject *args) +PyObject* MeshPy::writeInventor(PyObject* args) { - float creaseangle=0.0f; - if (!PyArg_ParseTuple(args, "|f",&creaseangle)) + float creaseangle = 0.0f; + if (!PyArg_ParseTuple(args, "|f", &creaseangle)) { return nullptr; + } std::stringstream result; MeshObject* mesh = getMeshObjectPtr(); @@ -311,39 +358,46 @@ PyObject* MeshPy::writeInventor(PyObject *args) return Py::new_reference_to(Py::String(result.str())); } -PyObject* MeshPy::offset(PyObject *args) +PyObject* MeshPy::offset(PyObject* args) { float Float; - if (!PyArg_ParseTuple(args, "f",&Float)) + if (!PyArg_ParseTuple(args, "f", &Float)) { return nullptr; + } - PY_TRY { + PY_TRY + { getMeshObjectPtr()->offsetSpecial2(Float); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::offsetSpecial(PyObject *args) +PyObject* MeshPy::offsetSpecial(PyObject* args) { - float Float,zmin,zmax; - if (!PyArg_ParseTuple(args, "fff",&Float,&zmin,&zmax)) + float Float, zmin, zmax; + if (!PyArg_ParseTuple(args, "fff", &Float, &zmin, &zmax)) { return nullptr; + } - PY_TRY { - getMeshObjectPtr()->offsetSpecial(Float,zmax,zmin); - } PY_CATCH; + PY_TRY + { + getMeshObjectPtr()->offsetSpecial(Float, zmax, zmin); + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::crossSections(PyObject *args) +PyObject* MeshPy::crossSections(PyObject* args) { - PyObject *obj; - PyObject *poly=Py_False; + PyObject* obj; + PyObject* poly = Py_False; float min_eps = 1.0e-2f; - if (!PyArg_ParseTuple(args, "O|fO!", &obj, &min_eps, &PyBool_Type, &poly)) + if (!PyArg_ParseTuple(args, "O|fO!", &obj, &min_eps, &PyBool_Type, &poly)) { return nullptr; + } Py::Sequence list(obj); Py::Type vType(Base::getTypeAsObject(&Base::VectorPy::Type)); @@ -357,8 +411,8 @@ PyObject* MeshPy::crossSections(PyObject *args) MeshObject::TPlane plane; Base::Vector3d b = static_cast(p1.ptr())->value(); Base::Vector3d n = static_cast(p2.ptr())->value(); - plane.first.Set((float)b.x,(float)b.y,(float)b.z); - plane.second.Set((float)n.x,(float)n.y,(float)n.z); + plane.first.Set((float)b.x, (float)b.y, (float)b.z); + plane.second.Set((float)n.x, (float)n.y, (float)n.z); csPlanes.push_back(plane); } else if (p1.isTuple() && p2.isTuple()) { @@ -372,8 +426,8 @@ PyObject* MeshPy::crossSections(PyObject *args) float nz = (float)Py::Float(n.getItem(2)); MeshObject::TPlane plane; - plane.first .Set(bx,by,bz); - plane.second.Set(nx,ny,nz); + plane.first.Set(bx, by, bz); + plane.second.Set(nx, ny, nz); csPlanes.push_back(plane); } } @@ -383,9 +437,9 @@ PyObject* MeshPy::crossSections(PyObject *args) // convert to Python objects Py::List crossSections; - for (const auto & it : sections) { + for (const auto& it : sections) { Py::List section; - for (const auto & jt : it) { + for (const auto& jt : it) { Py::List polyline; for (auto kt : jt) { polyline.append(Py::asObject(new Base::VectorPy(kt))); @@ -398,106 +452,134 @@ PyObject* MeshPy::crossSections(PyObject *args) return Py::new_reference_to(crossSections); } -PyObject* MeshPy::unite(PyObject *args) +PyObject* MeshPy::unite(PyObject* args) { - MeshPy *pcObject; - PyObject *pcObj; - if (!PyArg_ParseTuple(args, "O!", &(MeshPy::Type), &pcObj)) + MeshPy* pcObject; + PyObject* pcObj; + if (!PyArg_ParseTuple(args, "O!", &(MeshPy::Type), &pcObj)) { return nullptr; + } pcObject = static_cast(pcObj); - PY_TRY { + PY_TRY + { MeshObject* mesh = getMeshObjectPtr()->unite(*pcObject->getMeshObjectPtr()); return new MeshPy(mesh); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::intersect(PyObject *args) +PyObject* MeshPy::intersect(PyObject* args) { - MeshPy *pcObject; - PyObject *pcObj; - if (!PyArg_ParseTuple(args, "O!", &(MeshPy::Type), &pcObj)) + MeshPy* pcObject; + PyObject* pcObj; + if (!PyArg_ParseTuple(args, "O!", &(MeshPy::Type), &pcObj)) { return nullptr; + } pcObject = static_cast(pcObj); - PY_TRY { + PY_TRY + { MeshObject* mesh = getMeshObjectPtr()->intersect(*pcObject->getMeshObjectPtr()); return new MeshPy(mesh); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::difference(PyObject *args) +PyObject* MeshPy::difference(PyObject* args) { - MeshPy *pcObject; - PyObject *pcObj; - if (!PyArg_ParseTuple(args, "O!", &(MeshPy::Type), &pcObj)) + MeshPy* pcObject; + PyObject* pcObj; + if (!PyArg_ParseTuple(args, "O!", &(MeshPy::Type), &pcObj)) { return nullptr; + } pcObject = static_cast(pcObj); - PY_TRY { + PY_TRY + { MeshObject* mesh = getMeshObjectPtr()->subtract(*pcObject->getMeshObjectPtr()); return new MeshPy(mesh); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::inner(PyObject *args) +PyObject* MeshPy::inner(PyObject* args) { - MeshPy *pcObject; - PyObject *pcObj; - if (!PyArg_ParseTuple(args, "O!", &(MeshPy::Type), &pcObj)) + MeshPy* pcObject; + PyObject* pcObj; + if (!PyArg_ParseTuple(args, "O!", &(MeshPy::Type), &pcObj)) { return nullptr; + } pcObject = static_cast(pcObj); - PY_TRY { + PY_TRY + { MeshObject* mesh = getMeshObjectPtr()->inner(*pcObject->getMeshObjectPtr()); return new MeshPy(mesh); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::outer(PyObject *args) +PyObject* MeshPy::outer(PyObject* args) { - MeshPy *pcObject; - PyObject *pcObj; - if (!PyArg_ParseTuple(args, "O!", &(MeshPy::Type), &pcObj)) + MeshPy* pcObject; + PyObject* pcObj; + if (!PyArg_ParseTuple(args, "O!", &(MeshPy::Type), &pcObj)) { return nullptr; + } pcObject = static_cast(pcObj); - PY_TRY { + PY_TRY + { MeshObject* mesh = getMeshObjectPtr()->outer(*pcObject->getMeshObjectPtr()); return new MeshPy(mesh); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::section(PyObject *args, PyObject *kwds) +PyObject* MeshPy::section(PyObject* args, PyObject* kwds) { - PyObject *pcObj; - PyObject *connectLines = Py_True; + PyObject* pcObj; + PyObject* connectLines = Py_True; float fMinDist = 0.0001f; - static const std::array keywords_section {"Mesh", "ConnectLines", "MinDist", nullptr}; - if (!Base::Wrapped_ParseTupleAndKeywords(args, kwds, "O!|O!f",keywords_section, - &(MeshPy::Type), &pcObj, &PyBool_Type, &connectLines, &fMinDist)) { + static const std::array keywords_section {"Mesh", + "ConnectLines", + "MinDist", + nullptr}; + if (!Base::Wrapped_ParseTupleAndKeywords(args, + kwds, + "O!|O!f", + keywords_section, + &(MeshPy::Type), + &pcObj, + &PyBool_Type, + &connectLines, + &fMinDist)) { return nullptr; } MeshPy* pcObject = static_cast(pcObj); - std::vector< std::vector > curves = getMeshObjectPtr()->section(*pcObject->getMeshObjectPtr(), Base::asBoolean(connectLines), fMinDist); + std::vector> curves = + getMeshObjectPtr()->section(*pcObject->getMeshObjectPtr(), + Base::asBoolean(connectLines), + fMinDist); Py::List outer; for (const auto& it : curves) { Py::List inner; @@ -510,71 +592,83 @@ PyObject* MeshPy::section(PyObject *args, PyObject *kwds) return Py::new_reference_to(outer); } -PyObject* MeshPy::coarsen(PyObject *args) +PyObject* MeshPy::coarsen(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } PyErr_SetString(PyExc_NotImplementedError, "Not yet implemented"); return nullptr; } -PyObject* MeshPy::translate(PyObject *args) +PyObject* MeshPy::translate(PyObject* args) { - float x,y,z; - if (!PyArg_ParseTuple(args, "fff",&x,&y,&z)) + float x, y, z; + if (!PyArg_ParseTuple(args, "fff", &x, &y, &z)) { return nullptr; + } - PY_TRY { + PY_TRY + { Base::Matrix4D m; - m.move(x,y,z); + m.move(x, y, z); getMeshObjectPtr()->getKernel().Transform(m); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::rotate(PyObject *args) +PyObject* MeshPy::rotate(PyObject* args) { - double x,y,z; - if (!PyArg_ParseTuple(args, "ddd",&x,&y,&z)) + double x, y, z; + if (!PyArg_ParseTuple(args, "ddd", &x, &y, &z)) { return nullptr; + } - PY_TRY { + PY_TRY + { Base::Matrix4D m; m.rotX(x); m.rotY(y); m.rotZ(z); getMeshObjectPtr()->getKernel().Transform(m); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::transform(PyObject *args) +PyObject* MeshPy::transform(PyObject* args) { - PyObject *mat; - if (!PyArg_ParseTuple(args, "O!",&(Base::MatrixPy::Type), &mat)) + PyObject* mat; + if (!PyArg_ParseTuple(args, "O!", &(Base::MatrixPy::Type), &mat)) { return nullptr; + } - PY_TRY { + PY_TRY + { getMeshObjectPtr()->getKernel().Transform(static_cast(mat)->value()); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::transformToEigen(PyObject *args) +PyObject* MeshPy::transformToEigen(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } getMeshObjectPtr()->transformToEigenSystem(); Py_Return; } -PyObject* MeshPy::getEigenSystem(PyObject *args) +PyObject* MeshPy::getEigenSystem(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } Base::Vector3d vec; Base::Matrix4D mat = getMeshObjectPtr()->getEigenSystem(vec); Py::Tuple t(2); @@ -583,35 +677,40 @@ PyObject* MeshPy::getEigenSystem(PyObject *args) return Py::new_reference_to(t); } -PyObject* MeshPy::addFacet(PyObject *args) +PyObject* MeshPy::addFacet(PyObject* args) { - double x1,y1,z1,x2,y2,z2,x3,y3,z3; - if (PyArg_ParseTuple(args, "ddddddddd",&x1,&y1,&z1,&x2,&y2,&z2,&x3,&y3,&z3)) { - getMeshObjectPtr()->addFacet(MeshCore::MeshGeomFacet( - Base::Vector3f((float)x1,(float)y1,(float)z1), - Base::Vector3f((float)x2,(float)y2,(float)z2), - Base::Vector3f((float)x3,(float)y3,(float)z3))); + double x1, y1, z1, x2, y2, z2, x3, y3, z3; + if (PyArg_ParseTuple(args, "ddddddddd", &x1, &y1, &z1, &x2, &y2, &z2, &x3, &y3, &z3)) { + getMeshObjectPtr()->addFacet( + MeshCore::MeshGeomFacet(Base::Vector3f((float)x1, (float)y1, (float)z1), + Base::Vector3f((float)x2, (float)y2, (float)z2), + Base::Vector3f((float)x3, (float)y3, (float)z3))); Py_Return; } PyErr_Clear(); PyObject *v1, *v2, *v3; - if (PyArg_ParseTuple(args, "O!O!O!",&(Base::VectorPy::Type), &v1, - &(Base::VectorPy::Type), &v2, - &(Base::VectorPy::Type), &v3)) { - Base::Vector3d *p1 = static_cast(v1)->getVectorPtr(); - Base::Vector3d *p2 = static_cast(v2)->getVectorPtr(); - Base::Vector3d *p3 = static_cast(v3)->getVectorPtr(); - getMeshObjectPtr()->addFacet(MeshCore::MeshGeomFacet( - Base::Vector3f((float)p1->x,(float)p1->y,(float)p1->z), - Base::Vector3f((float)p2->x,(float)p2->y,(float)p2->z), - Base::Vector3f((float)p3->x,(float)p3->y,(float)p3->z))); + if (PyArg_ParseTuple(args, + "O!O!O!", + &(Base::VectorPy::Type), + &v1, + &(Base::VectorPy::Type), + &v2, + &(Base::VectorPy::Type), + &v3)) { + Base::Vector3d* p1 = static_cast(v1)->getVectorPtr(); + Base::Vector3d* p2 = static_cast(v2)->getVectorPtr(); + Base::Vector3d* p3 = static_cast(v3)->getVectorPtr(); + getMeshObjectPtr()->addFacet( + MeshCore::MeshGeomFacet(Base::Vector3f((float)p1->x, (float)p1->y, (float)p1->z), + Base::Vector3f((float)p2->x, (float)p2->y, (float)p2->z), + Base::Vector3f((float)p3->x, (float)p3->y, (float)p3->z))); Py_Return; } PyErr_Clear(); - PyObject *f; - if (PyArg_ParseTuple(args, "O!",&(Mesh::FacetPy::Type), &f)) { + PyObject* f; + if (PyArg_ParseTuple(args, "O!", &(Mesh::FacetPy::Type), &f)) { Mesh::FacetPy* face = static_cast(f); getMeshObjectPtr()->addFacet(*face->getFacetPtr()); Py_Return; @@ -621,9 +720,9 @@ PyObject* MeshPy::addFacet(PyObject *args) return nullptr; } -PyObject* MeshPy::addFacets(PyObject *args) +PyObject* MeshPy::addFacets(PyObject* args) { - PyObject *list; + PyObject* list; if (PyArg_ParseTuple(args, "O!", &PyList_Type, &list)) { Py::List list_f(list); Py::Type vVType(Base::getTypeAsObject(&Base::VectorPy::Type)); @@ -649,15 +748,15 @@ PyObject* MeshPy::addFacets(PyObject *args) } else if (seq[0].isSequence()) { // a sequence of sequence of flots - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { facet._aclPoints[i] = Base::getVectorFromTuple(seq[i].ptr()); } } else if (PyObject_TypeCheck(seq[0].ptr(), &(Base::VectorPy::Type))) { // a sequence of vectors - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { Base::Vector3d p = Py::Vector(seq[i]).toVector(); - facet._aclPoints[i].Set((float)p.x,(float)p.y,(float)p.z); + facet._aclPoints[i].Set((float)p.x, (float)p.y, (float)p.z); } } else { @@ -670,8 +769,8 @@ PyObject* MeshPy::addFacets(PyObject *args) } else { // 9 consecutive floats expected - int index=0; - for (auto & point : facet._aclPoints) { + int index = 0; + for (auto& point : facet._aclPoints) { point.x = (float)(double)Py::Float(seq[index++]); point.y = (float)(double)Py::Float(seq[index++]); point.z = (float)(double)Py::Float(seq[index++]); @@ -679,7 +778,7 @@ PyObject* MeshPy::addFacets(PyObject *args) facet.CalcNormal(); facets.push_back(facet); } - } // sequence + } // sequence } getMeshObjectPtr()->addFacets(facets); @@ -687,7 +786,7 @@ PyObject* MeshPy::addFacets(PyObject *args) } PyErr_Clear(); - PyObject *check = Py_True; + PyObject* check = Py_True; if (PyArg_ParseTuple(args, "O!|O!", &PyTuple_Type, &list, &PyBool_Type, &check)) { Py::Tuple tuple(list); Py::List list_v(tuple.getItem(0)); @@ -696,7 +795,7 @@ PyObject* MeshPy::addFacets(PyObject *args) for (Py::List::iterator it = list_v.begin(); it != list_v.end(); ++it) { if ((*it).isType(vType)) { Base::Vector3d v = static_cast((*it).ptr())->value(); - vertices.emplace_back((float)v.x,(float)v.y,(float)v.z); + vertices.emplace_back((float)v.x, (float)v.y, (float)v.z); } } @@ -716,17 +815,19 @@ PyObject* MeshPy::addFacets(PyObject *args) Py_Return; } - PyErr_SetString(PyExc_TypeError, "either expect\n" - "-- [Vector] (3 of them define a facet)\n" - "-- ([Vector],[(int,int,int)])"); + PyErr_SetString(PyExc_TypeError, + "either expect\n" + "-- [Vector] (3 of them define a facet)\n" + "-- ([Vector],[(int,int,int)])"); return nullptr; } -PyObject* MeshPy::removeFacets(PyObject *args) +PyObject* MeshPy::removeFacets(PyObject* args) { PyObject* list; - if (!PyArg_ParseTuple(args, "O", &list)) + if (!PyArg_ParseTuple(args, "O", &list)) { return nullptr; + } std::vector indices; Py::Sequence ary(list); @@ -739,10 +840,11 @@ PyObject* MeshPy::removeFacets(PyObject *args) Py_Return; } -PyObject* MeshPy::getInternalFacets(PyObject *args) +PyObject* MeshPy::getInternalFacets(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } const MeshCore::MeshKernel& kernel = getMeshObjectPtr()->getKernel(); MeshCore::MeshEvalInternalFacets eval(kernel); @@ -750,7 +852,7 @@ PyObject* MeshPy::getInternalFacets(PyObject *args) const std::vector& indices = eval.GetIndices(); Py::List ary(indices.size()); - Py::List::size_type pos=0; + Py::List::size_type pos = 0; for (FacetIndex index : indices) { ary[pos++] = Py::Long(index); } @@ -758,92 +860,102 @@ PyObject* MeshPy::getInternalFacets(PyObject *args) return Py::new_reference_to(ary); } -PyObject* MeshPy::rebuildNeighbourHood(PyObject *args) +PyObject* MeshPy::rebuildNeighbourHood(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } MeshCore::MeshKernel& kernel = getMeshObjectPtr()->getKernel(); kernel.RebuildNeighbours(); Py_Return; } -PyObject* MeshPy::addMesh(PyObject *args) +PyObject* MeshPy::addMesh(PyObject* args) { PyObject* mesh; - if (!PyArg_ParseTuple(args, "O!",&(MeshPy::Type), &mesh)) + if (!PyArg_ParseTuple(args, "O!", &(MeshPy::Type), &mesh)) { return nullptr; + } - PY_TRY { + PY_TRY + { getMeshObjectPtr()->addMesh(*static_cast(mesh)->getMeshObjectPtr()); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::setPoint(PyObject *args) +PyObject* MeshPy::setPoint(PyObject* args) { unsigned long index; PyObject* pnt; - if (!PyArg_ParseTuple(args, "kO!",&index, &(Base::VectorPy::Type), &pnt)) + if (!PyArg_ParseTuple(args, "kO!", &index, &(Base::VectorPy::Type), &pnt)) { return nullptr; + } - PY_TRY { + PY_TRY + { getMeshObjectPtr()->setPoint(index, static_cast(pnt)->value()); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::movePoint(PyObject *args) +PyObject* MeshPy::movePoint(PyObject* args) { unsigned long index; Base::Vector3d vec; do { - double x=0.0,y=0.0,z=0.0; - if (PyArg_ParseTuple(args, "kddd", &index,&x,&y,&z)) { - vec.Set(x,y,z); + double x = 0.0, y = 0.0, z = 0.0; + if (PyArg_ParseTuple(args, "kddd", &index, &x, &y, &z)) { + vec.Set(x, y, z); break; } - PyErr_Clear(); // set by PyArg_ParseTuple() - PyObject *object; - if (PyArg_ParseTuple(args,"kO!", &index, &(Base::VectorPy::Type), &object)) { + PyErr_Clear(); // set by PyArg_ParseTuple() + PyObject* object; + if (PyArg_ParseTuple(args, "kO!", &index, &(Base::VectorPy::Type), &object)) { vec = *(static_cast(object)->getVectorPtr()); break; } PyErr_SetString(PyExc_TypeError, "Tuple of three floats or Vector expected"); return nullptr; - } - while (false); + } while (false); getMeshObjectPtr()->movePoint(index, vec); Py_Return; } -PyObject* MeshPy::getPointNormals(PyObject *args) +PyObject* MeshPy::getPointNormals(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { std::vector normals = getMeshObjectPtr()->getPointNormals(); Py::Tuple ary(normals.size()); std::size_t numNormals = normals.size(); - for (std::size_t i=0; i segment; @@ -852,28 +964,31 @@ PyObject* MeshPy::addSegment(PyObject *args) for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { Py::Long value(*it); Mesh::FacetIndex index = static_cast(value); - if (index < numFacets) + if (index < numFacets) { segment.push_back(index); + } } getMeshObjectPtr()->addSegment(segment); Py_Return; } -PyObject* MeshPy::countSegments(PyObject *args) +PyObject* MeshPy::countSegments(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } unsigned long count = getMeshObjectPtr()->countSegments(); - return Py_BuildValue("k",count); + return Py_BuildValue("k", count); } -PyObject* MeshPy::getSegment(PyObject *args) +PyObject* MeshPy::getSegment(PyObject* args) { unsigned long index; - if (!PyArg_ParseTuple(args, "k", &index)) + if (!PyArg_ParseTuple(args, "k", &index)) { return nullptr; + } unsigned long count = getMeshObjectPtr()->countSegments(); if (index >= count) { @@ -890,25 +1005,27 @@ PyObject* MeshPy::getSegment(PyObject *args) return Py::new_reference_to(ary); } -PyObject* MeshPy::getSeparateComponents(PyObject *args) +PyObject* MeshPy::getSeparateComponents(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } Py::List meshesList; - std::vector > segs; + std::vector> segs; segs = getMeshObjectPtr()->getComponents(); - for (const auto & it : segs) { + for (const auto& it : segs) { MeshObject* mesh = getMeshObjectPtr()->meshFromSegment(it); - meshesList.append(Py::Object(new MeshPy(mesh),true)); + meshesList.append(Py::Object(new MeshPy(mesh), true)); } return Py::new_reference_to(meshesList); } -PyObject* MeshPy::getFacetSelection(PyObject *args) +PyObject* MeshPy::getFacetSelection(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } Py::List ary; std::vector facets; @@ -920,10 +1037,11 @@ PyObject* MeshPy::getFacetSelection(PyObject *args) return Py::new_reference_to(ary); } -PyObject* MeshPy::getPointSelection(PyObject *args) +PyObject* MeshPy::getPointSelection(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } Py::List ary; std::vector points; @@ -935,11 +1053,12 @@ PyObject* MeshPy::getPointSelection(PyObject *args) return Py::new_reference_to(ary); } -PyObject* MeshPy::meshFromSegment(PyObject *args) +PyObject* MeshPy::meshFromSegment(PyObject* args) { PyObject* list; - if (!PyArg_ParseTuple(args, "O", &list)) + if (!PyArg_ParseTuple(args, "O", &list)) { return nullptr; + } std::vector segment; Py::Sequence ary(list); @@ -953,92 +1072,103 @@ PyObject* MeshPy::meshFromSegment(PyObject *args) return new MeshPy(mesh); } -PyObject* MeshPy::clear(PyObject *args) +PyObject* MeshPy::clear(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } getMeshObjectPtr()->clear(); Py_Return; } -PyObject* MeshPy::isSolid(PyObject *args) +PyObject* MeshPy::isSolid(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } bool ok = getMeshObjectPtr()->isSolid(); return Py_BuildValue("O", (ok ? Py_True : Py_False)); } -PyObject* MeshPy::hasNonManifolds(PyObject *args) +PyObject* MeshPy::hasNonManifolds(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } bool ok = getMeshObjectPtr()->hasNonManifolds(); return Py_BuildValue("O", (ok ? Py_True : Py_False)); } -PyObject* MeshPy::hasInvalidNeighbourhood(PyObject *args) +PyObject* MeshPy::hasInvalidNeighbourhood(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } bool ok = getMeshObjectPtr()->hasInvalidNeighbourhood(); return Py_BuildValue("O", (ok ? Py_True : Py_False)); } -PyObject* MeshPy::hasPointsOutOfRange(PyObject *args) +PyObject* MeshPy::hasPointsOutOfRange(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } bool ok = getMeshObjectPtr()->hasPointsOutOfRange(); return Py_BuildValue("O", (ok ? Py_True : Py_False)); } -PyObject* MeshPy::hasFacetsOutOfRange(PyObject *args) +PyObject* MeshPy::hasFacetsOutOfRange(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } bool ok = getMeshObjectPtr()->hasFacetsOutOfRange(); return Py_BuildValue("O", (ok ? Py_True : Py_False)); } -PyObject* MeshPy::hasCorruptedFacets(PyObject *args) +PyObject* MeshPy::hasCorruptedFacets(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } bool ok = getMeshObjectPtr()->hasFacetsOutOfRange(); return Py_BuildValue("O", (ok ? Py_True : Py_False)); } -PyObject* MeshPy::removeNonManifolds(PyObject *args) +PyObject* MeshPy::removeNonManifolds(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } getMeshObjectPtr()->removeNonManifolds(); Py_Return; } -PyObject* MeshPy::removeNonManifoldPoints(PyObject *args) +PyObject* MeshPy::removeNonManifoldPoints(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } getMeshObjectPtr()->removeNonManifoldPoints(); Py_Return; } -PyObject* MeshPy::hasSelfIntersections(PyObject *args) +PyObject* MeshPy::hasSelfIntersections(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } bool ok = getMeshObjectPtr()->hasSelfIntersections(); return Py_BuildValue("O", (ok ? Py_True : Py_False)); } -PyObject* MeshPy::getSelfIntersections(PyObject *args) +PyObject* MeshPy::getSelfIntersections(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - std::vector > selfIndices; + std::vector> selfIndices; std::vector selfLines; selfIndices = getMeshObjectPtr()->getSelfIntersections(); @@ -1046,7 +1176,7 @@ PyObject* MeshPy::getSelfIntersections(PyObject *args) Py::Tuple tuple(selfIndices.size()); if (selfIndices.size() == selfLines.size()) { - for (std::size_t i=0; iremoveSelfIntersections(); } @@ -1073,10 +1204,11 @@ PyObject* MeshPy::fixSelfIntersections(PyObject *args) Py_Return; } -PyObject* MeshPy::removeFoldsOnSurface(PyObject *args) +PyObject* MeshPy::removeFoldsOnSurface(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } try { getMeshObjectPtr()->removeFoldsOnSurface(); } @@ -1087,18 +1219,20 @@ PyObject* MeshPy::removeFoldsOnSurface(PyObject *args) Py_Return; } -PyObject* MeshPy::hasInvalidPoints(PyObject *args) +PyObject* MeshPy::hasInvalidPoints(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } bool ok = getMeshObjectPtr()->hasInvalidPoints(); return Py_BuildValue("O", (ok ? Py_True : Py_False)); } -PyObject* MeshPy::removeInvalidPoints(PyObject *args) +PyObject* MeshPy::removeInvalidPoints(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } try { getMeshObjectPtr()->removeInvalidPoints(); } @@ -1109,19 +1243,25 @@ PyObject* MeshPy::removeInvalidPoints(PyObject *args) Py_Return; } -PyObject* MeshPy::hasPointsOnEdge(PyObject *args) +PyObject* MeshPy::hasPointsOnEdge(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } bool ok = getMeshObjectPtr()->hasPointsOnEdge(); return Py_BuildValue("O", (ok ? Py_True : Py_False)); } -PyObject* MeshPy::removePointsOnEdge(PyObject *args, PyObject *kwds) +PyObject* MeshPy::removePointsOnEdge(PyObject* args, PyObject* kwds) { - PyObject *fillBoundary = Py_False; // NOLINT - static const std::array keywords {"FillBoundary", nullptr}; - if (!Base::Wrapped_ParseTupleAndKeywords(args, kwds, "|O!", keywords, &PyBool_Type, &fillBoundary)) { + PyObject* fillBoundary = Py_False; // NOLINT + static const std::array keywords {"FillBoundary", nullptr}; + if (!Base::Wrapped_ParseTupleAndKeywords(args, + kwds, + "|O!", + keywords, + &PyBool_Type, + &fillBoundary)) { return nullptr; } try { @@ -1134,104 +1274,118 @@ PyObject* MeshPy::removePointsOnEdge(PyObject *args, PyObject *kwds) Py_Return; } -PyObject* MeshPy::flipNormals(PyObject *args) +PyObject* MeshPy::flipNormals(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { MeshPropertyLock lock(this->parentProperty); getMeshObjectPtr()->flipNormals(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::hasNonUniformOrientedFacets(PyObject *args) +PyObject* MeshPy::hasNonUniformOrientedFacets(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } bool ok = getMeshObjectPtr()->countNonUniformOrientedFacets() > 0; return Py_BuildValue("O", (ok ? Py_True : Py_False)); } -PyObject* MeshPy::countNonUniformOrientedFacets(PyObject *args) +PyObject* MeshPy::countNonUniformOrientedFacets(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } unsigned long count = getMeshObjectPtr()->countNonUniformOrientedFacets(); return Py_BuildValue("k", count); } -PyObject* MeshPy::getNonUniformOrientedFacets(PyObject *args) +PyObject* MeshPy::getNonUniformOrientedFacets(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } const MeshCore::MeshKernel& kernel = getMeshObjectPtr()->getKernel(); MeshCore::MeshEvalOrientation cMeshEval(kernel); std::vector inds = cMeshEval.GetIndices(); Py::Tuple tuple(inds.size()); - for (std::size_t i=0; iparentProperty); getMeshObjectPtr()->harmonizeNormals(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::countComponents(PyObject *args) +PyObject* MeshPy::countComponents(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } unsigned long count = getMeshObjectPtr()->countComponents(); - return Py_BuildValue("k",count); + return Py_BuildValue("k", count); } -PyObject* MeshPy::removeComponents(PyObject *args) +PyObject* MeshPy::removeComponents(PyObject* args) { unsigned long count; - if (!PyArg_ParseTuple(args, "k", &count)) + if (!PyArg_ParseTuple(args, "k", &count)) { return nullptr; + } - PY_TRY { + PY_TRY + { if (count > 0) { getMeshObjectPtr()->removeComponents(count); } - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::fillupHoles(PyObject *args) +PyObject* MeshPy::fillupHoles(PyObject* args) { unsigned long len; int level = 0; float max_area = 0.0f; - if (!PyArg_ParseTuple(args, "k|if", &len,&level,&max_area)) + if (!PyArg_ParseTuple(args, "k|if", &len, &level, &max_area)) { return nullptr; + } try { std::unique_ptr tria; if (max_area > 0.0f) { - tria = std::unique_ptr - (new MeshCore::ConstraintDelaunayTriangulator(max_area)); + tria = std::unique_ptr( + new MeshCore::ConstraintDelaunayTriangulator(max_area)); } else { - tria = std::unique_ptr - (new MeshCore::FlatTriangulator()); + tria = std::unique_ptr( + new MeshCore::FlatTriangulator()); } MeshPropertyLock lock(this->parentProperty); @@ -1246,184 +1400,228 @@ PyObject* MeshPy::fillupHoles(PyObject *args) Py_Return; } -PyObject* MeshPy::fixIndices(PyObject *args) +PyObject* MeshPy::fixIndices(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { getMeshObjectPtr()->validateIndices(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::fixCaps(PyObject *args) +PyObject* MeshPy::fixCaps(PyObject* args) { float fMaxAngle = Base::toRadians(150.0f); float fSplitFactor = 0.25f; - if (!PyArg_ParseTuple(args, "|ff", &fMaxAngle, &fSplitFactor)) + if (!PyArg_ParseTuple(args, "|ff", &fMaxAngle, &fSplitFactor)) { return nullptr; + } - PY_TRY { + PY_TRY + { getMeshObjectPtr()->validateCaps(fMaxAngle, fSplitFactor); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::fixDeformations(PyObject *args) +PyObject* MeshPy::fixDeformations(PyObject* args) { float fMaxAngle; float fEpsilon = MeshCore::MeshDefinitions::_fMinPointDistanceP2; - if (!PyArg_ParseTuple(args, "f|f", &fMaxAngle, &fEpsilon)) + if (!PyArg_ParseTuple(args, "f|f", &fMaxAngle, &fEpsilon)) { return nullptr; + } - PY_TRY { + PY_TRY + { getMeshObjectPtr()->validateDeformations(fMaxAngle, fEpsilon); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::fixDegenerations(PyObject *args) +PyObject* MeshPy::fixDegenerations(PyObject* args) { float fEpsilon = MeshCore::MeshDefinitions::_fMinPointDistanceP2; - if (!PyArg_ParseTuple(args, "|f", &fEpsilon)) + if (!PyArg_ParseTuple(args, "|f", &fEpsilon)) { return nullptr; + } - PY_TRY { + PY_TRY + { getMeshObjectPtr()->validateDegenerations(fEpsilon); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::removeDuplicatedPoints(PyObject *args) +PyObject* MeshPy::removeDuplicatedPoints(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { getMeshObjectPtr()->removeDuplicatedPoints(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::removeDuplicatedFacets(PyObject *args) +PyObject* MeshPy::removeDuplicatedFacets(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { getMeshObjectPtr()->removeDuplicatedFacets(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::refine(PyObject *args) +PyObject* MeshPy::refine(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { getMeshObjectPtr()->refine(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::removeNeedles(PyObject *args) +PyObject* MeshPy::removeNeedles(PyObject* args) { float length; - if (!PyArg_ParseTuple(args, "f", &length)) + if (!PyArg_ParseTuple(args, "f", &length)) { return nullptr; + } - PY_TRY { + PY_TRY + { getMeshObjectPtr()->removeNeedles(length); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::removeFullBoundaryFacets(PyObject *args) +PyObject* MeshPy::removeFullBoundaryFacets(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { getMeshObjectPtr()->removeFullBoundaryFacets(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::mergeFacets(PyObject *args) +PyObject* MeshPy::mergeFacets(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { getMeshObjectPtr()->mergeFacets(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::optimizeTopology(PyObject *args) +PyObject* MeshPy::optimizeTopology(PyObject* args) { - float fMaxAngle=-1.0f; - if (!PyArg_ParseTuple(args, "|f; specify the maximum allowed angle between the normals of two adjacent facets", &fMaxAngle)) + float fMaxAngle = -1.0f; + if (!PyArg_ParseTuple( + args, + "|f; specify the maximum allowed angle between the normals of two adjacent facets", + &fMaxAngle)) { return nullptr; + } - PY_TRY { + PY_TRY + { MeshPropertyLock lock(this->parentProperty); getMeshObjectPtr()->optimizeTopology(fMaxAngle); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::optimizeEdges(PyObject *args) +PyObject* MeshPy::optimizeEdges(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { MeshPropertyLock lock(this->parentProperty); getMeshObjectPtr()->optimizeEdges(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::splitEdges(PyObject *args) +PyObject* MeshPy::splitEdges(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } - PY_TRY { + PY_TRY + { getMeshObjectPtr()->splitEdges(); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::splitEdge(PyObject *args) +PyObject* MeshPy::splitEdge(PyObject* args) { unsigned long facet, neighbour; PyObject* vertex; - if (!PyArg_ParseTuple(args, "kkO!", &facet, &neighbour, &Base::VectorPy::Type, &vertex)) + if (!PyArg_ParseTuple(args, "kkO!", &facet, &neighbour, &Base::VectorPy::Type, &vertex)) { return nullptr; + } - Base::VectorPy *pcObject = static_cast(vertex); + Base::VectorPy* pcObject = static_cast(vertex); Base::Vector3d* val = pcObject->getVectorPtr(); - Base::Vector3f v((float)val->x,(float)val->y,(float)val->z); + Base::Vector3f v((float)val->x, (float)val->y, (float)val->z); const MeshCore::MeshKernel& kernel = getMeshObjectPtr()->getKernel(); - PY_TRY { + PY_TRY + { if (facet >= kernel.CountFacets()) { PyErr_SetString(PyExc_IndexError, "Facet index out of range"); return nullptr; @@ -1434,56 +1632,67 @@ PyObject* MeshPy::splitEdge(PyObject *args) } const MeshCore::MeshFacet& rclF = kernel.GetFacets()[facet]; - if (rclF._aulNeighbours[0] != neighbour && rclF._aulNeighbours[1] != neighbour && - rclF._aulNeighbours[2] != neighbour) { + if (rclF._aulNeighbours[0] != neighbour && rclF._aulNeighbours[1] != neighbour + && rclF._aulNeighbours[2] != neighbour) { PyErr_SetString(PyExc_IndexError, "No adjacent facets"); return nullptr; } getMeshObjectPtr()->splitEdge(facet, neighbour, v); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::splitFacet(PyObject *args) +PyObject* MeshPy::splitFacet(PyObject* args) { unsigned long facet; PyObject* vertex1; PyObject* vertex2; - if (!PyArg_ParseTuple(args, "kO!O!", &facet, &Base::VectorPy::Type, &vertex1, - &Base::VectorPy::Type, &vertex2)) + if (!PyArg_ParseTuple(args, + "kO!O!", + &facet, + &Base::VectorPy::Type, + &vertex1, + &Base::VectorPy::Type, + &vertex2)) { return nullptr; + } - Base::VectorPy *pcObject = static_cast(vertex1); + Base::VectorPy* pcObject = static_cast(vertex1); Base::Vector3d* val = pcObject->getVectorPtr(); - Base::Vector3f v1((float)val->x,(float)val->y,(float)val->z); + Base::Vector3f v1((float)val->x, (float)val->y, (float)val->z); pcObject = static_cast(vertex2); val = pcObject->getVectorPtr(); - Base::Vector3f v2((float)val->x,(float)val->y,(float)val->z); + Base::Vector3f v2((float)val->x, (float)val->y, (float)val->z); const MeshCore::MeshKernel& kernel = getMeshObjectPtr()->getKernel(); - PY_TRY { + PY_TRY + { if (facet >= kernel.CountFacets()) { PyErr_SetString(PyExc_IndexError, "Facet index out of range"); return nullptr; } getMeshObjectPtr()->splitFacet(facet, v1, v2); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::swapEdge(PyObject *args) +PyObject* MeshPy::swapEdge(PyObject* args) { unsigned long facet, neighbour; - if (!PyArg_ParseTuple(args, "kk", &facet, &neighbour)) + if (!PyArg_ParseTuple(args, "kk", &facet, &neighbour)) { return nullptr; + } const MeshCore::MeshKernel& kernel = getMeshObjectPtr()->getKernel(); - PY_TRY { + PY_TRY + { if (facet >= kernel.CountFacets()) { PyErr_SetString(PyExc_IndexError, "Facet index out of range"); return nullptr; @@ -1494,26 +1703,29 @@ PyObject* MeshPy::swapEdge(PyObject *args) } const MeshCore::MeshFacet& rclF = kernel.GetFacets()[facet]; - if (rclF._aulNeighbours[0] != neighbour && rclF._aulNeighbours[1] != neighbour && - rclF._aulNeighbours[2] != neighbour) { + if (rclF._aulNeighbours[0] != neighbour && rclF._aulNeighbours[1] != neighbour + && rclF._aulNeighbours[2] != neighbour) { PyErr_SetString(PyExc_IndexError, "No adjacent facets"); return nullptr; } getMeshObjectPtr()->swapEdge(facet, neighbour); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::collapseEdge(PyObject *args) +PyObject* MeshPy::collapseEdge(PyObject* args) { unsigned long facet, neighbour; - if (!PyArg_ParseTuple(args, "kk", &facet, &neighbour)) + if (!PyArg_ParseTuple(args, "kk", &facet, &neighbour)) { return nullptr; + } const MeshCore::MeshKernel& kernel = getMeshObjectPtr()->getKernel(); - PY_TRY { + PY_TRY + { if (facet >= kernel.CountFacets()) { PyErr_SetString(PyExc_IndexError, "Facet index out of range"); return nullptr; @@ -1524,94 +1736,106 @@ PyObject* MeshPy::collapseEdge(PyObject *args) } const MeshCore::MeshFacet& rclF = kernel.GetFacets()[facet]; - if (rclF._aulNeighbours[0] != neighbour && rclF._aulNeighbours[1] != neighbour && - rclF._aulNeighbours[2] != neighbour) { + if (rclF._aulNeighbours[0] != neighbour && rclF._aulNeighbours[1] != neighbour + && rclF._aulNeighbours[2] != neighbour) { PyErr_SetString(PyExc_IndexError, "No adjacent facets"); return nullptr; } getMeshObjectPtr()->collapseEdge(facet, neighbour); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::collapseFacet(PyObject *args) +PyObject* MeshPy::collapseFacet(PyObject* args) { unsigned long facet; - if (!PyArg_ParseTuple(args, "k", &facet)) + if (!PyArg_ParseTuple(args, "k", &facet)) { return nullptr; + } - PY_TRY { + PY_TRY + { if (facet >= getMeshObjectPtr()->countFacets()) { PyErr_SetString(PyExc_IndexError, "Facet index out of range"); return nullptr; } getMeshObjectPtr()->collapseFacet(facet); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::insertVertex(PyObject *args) +PyObject* MeshPy::insertVertex(PyObject* args) { unsigned long facet; PyObject* vertex; - if (!PyArg_ParseTuple(args, "kO!", &facet, &Base::VectorPy::Type, &vertex)) + if (!PyArg_ParseTuple(args, "kO!", &facet, &Base::VectorPy::Type, &vertex)) { return nullptr; + } - Base::VectorPy *pcObject = static_cast(vertex); + Base::VectorPy* pcObject = static_cast(vertex); Base::Vector3d* val = pcObject->getVectorPtr(); - Base::Vector3f v((float)val->x,(float)val->y,(float)val->z); + Base::Vector3f v((float)val->x, (float)val->y, (float)val->z); - PY_TRY { + PY_TRY + { if (facet >= getMeshObjectPtr()->countFacets()) { PyErr_SetString(PyExc_IndexError, "Facet index out of range"); return nullptr; } getMeshObjectPtr()->insertVertex(facet, v); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::snapVertex(PyObject *args) +PyObject* MeshPy::snapVertex(PyObject* args) { unsigned long facet; PyObject* vertex; - if (!PyArg_ParseTuple(args, "kO!", &facet, &Base::VectorPy::Type, &vertex)) + if (!PyArg_ParseTuple(args, "kO!", &facet, &Base::VectorPy::Type, &vertex)) { return nullptr; + } - Base::VectorPy *pcObject = static_cast(vertex); + Base::VectorPy* pcObject = static_cast(vertex); Base::Vector3d* val = pcObject->getVectorPtr(); - Base::Vector3f v((float)val->x,(float)val->y,(float)val->z); + Base::Vector3f v((float)val->x, (float)val->y, (float)val->z); - PY_TRY { + PY_TRY + { if (facet >= getMeshObjectPtr()->countFacets()) { PyErr_SetString(PyExc_IndexError, "Facet index out of range"); return nullptr; } getMeshObjectPtr()->snapVertex(facet, v); - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::printInfo(PyObject *args) +PyObject* MeshPy::printInfo(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } return Py_BuildValue("s", getMeshObjectPtr()->topologyInfo().c_str()); } -PyObject* MeshPy::collapseFacets(PyObject *args) +PyObject* MeshPy::collapseFacets(PyObject* args) { - PyObject *pcObj=nullptr; - if (!PyArg_ParseTuple(args, "O", &pcObj)) + PyObject* pcObj = nullptr; + if (!PyArg_ParseTuple(args, "O", &pcObj)) { return nullptr; + } // if no mesh is given try { @@ -1632,20 +1856,20 @@ PyObject* MeshPy::collapseFacets(PyObject *args) Py_Return; } -PyObject* MeshPy::foraminate(PyObject *args) +PyObject* MeshPy::foraminate(PyObject* args) { PyObject* pnt_p; PyObject* dir_p; double maxAngle = MeshCore::Mathd::PI; - if (!PyArg_ParseTuple(args, "OO|d", &pnt_p, &dir_p, &maxAngle)) + if (!PyArg_ParseTuple(args, "OO|d", &pnt_p, &dir_p, &maxAngle)) { return nullptr; + } try { Py::Vector pnt_t(pnt_p, false); Py::Vector dir_t(dir_p, false); - MeshObject::TRay ray = std::make_pair(pnt_t.toVector(), - dir_t.toVector()); + MeshObject::TRay ray = std::make_pair(pnt_t.toVector(), dir_t.toVector()); auto output = getMeshObjectPtr()->foraminate(ray, maxAngle); Py::Dict dict; @@ -1664,12 +1888,13 @@ PyObject* MeshPy::foraminate(PyObject *args) } } -PyObject* MeshPy::cut(PyObject *args) +PyObject* MeshPy::cut(PyObject* args) { PyObject* poly; int mode; - if (!PyArg_ParseTuple(args, "Oi", &poly, &mode)) + if (!PyArg_ParseTuple(args, "Oi", &poly, &mode)) { return nullptr; + } Py::Sequence list(poly); std::vector polygon; @@ -1691,19 +1916,21 @@ PyObject* MeshPy::cut(PyObject *args) Base::ViewProjMatrix proj(mat); Base::Polygon2d polygon2d; - for (auto it : polygon) + for (auto it : polygon) { polygon2d.Add(Base::Vector2d(it.x, it.y)); + } getMeshObjectPtr()->cut(polygon2d, proj, MeshObject::CutType(mode)); Py_Return; } -PyObject* MeshPy::trim(PyObject *args) +PyObject* MeshPy::trim(PyObject* args) { PyObject* poly; int mode; - if (!PyArg_ParseTuple(args, "Oi", &poly, &mode)) + if (!PyArg_ParseTuple(args, "Oi", &poly, &mode)) { return nullptr; + } Py::Sequence list(poly); std::vector polygon; @@ -1725,19 +1952,25 @@ PyObject* MeshPy::trim(PyObject *args) Base::ViewOrthoProjMatrix proj(mat); Base::Polygon2d polygon2d; - for (auto it : polygon) + for (auto it : polygon) { polygon2d.Add(Base::Vector2d(it.x, it.y)); + } getMeshObjectPtr()->trim(polygon2d, proj, MeshObject::CutType(mode)); Py_Return; } -PyObject* MeshPy::trimByPlane(PyObject *args) +PyObject* MeshPy::trimByPlane(PyObject* args) { PyObject *base, *norm; - if (!PyArg_ParseTuple(args, "O!O!", &Base::VectorPy::Type, &base, - &Base::VectorPy::Type, &norm)) + if (!PyArg_ParseTuple(args, + "O!O!", + &Base::VectorPy::Type, + &base, + &Base::VectorPy::Type, + &norm)) { return nullptr; + } Base::Vector3d pnt = Py::Vector(base, false).toVector(); Base::Vector3d dir = Py::Vector(norm, false).toVector(); @@ -1748,36 +1981,48 @@ PyObject* MeshPy::trimByPlane(PyObject *args) Py_Return; } -PyObject* MeshPy::smooth(PyObject *args, PyObject *kwds) +PyObject* MeshPy::smooth(PyObject* args, PyObject* kwds) { char* method = "Laplace"; - int iter=1; + int iter = 1; double lambda = 0; double micro = 0; double maximum = 1000; int weight = 1; - static const std::array keywords_smooth{"Method", "Iteration", "Lambda", "Micro", "Maximum", - "Weight", nullptr}; - if (!Base::Wrapped_ParseTupleAndKeywords(args, kwds, "|sidddi",keywords_smooth, - &method, &iter, &lambda, µ, &maximum, &weight)) { + static const std::array + keywords_smooth {"Method", "Iteration", "Lambda", "Micro", "Maximum", "Weight", nullptr}; + if (!Base::Wrapped_ParseTupleAndKeywords(args, + kwds, + "|sidddi", + keywords_smooth, + &method, + &iter, + &lambda, + µ, + &maximum, + &weight)) { return nullptr; } - PY_TRY { + PY_TRY + { MeshPropertyLock lock(this->parentProperty); MeshCore::MeshKernel& kernel = getMeshObjectPtr()->getKernel(); if (strcmp(method, "Laplace") == 0) { MeshCore::LaplaceSmoothing smooth(kernel); - if (lambda > 0) + if (lambda > 0) { smooth.SetLambda(lambda); + } smooth.Smooth(iter); } else if (strcmp(method, "Taubin") == 0) { MeshCore::TaubinSmoothing smooth(kernel); - if (lambda > 0) + if (lambda > 0) { smooth.SetLambda(lambda); - if (micro > 0) + } + if (micro > 0) { smooth.SetMicro(micro); + } smooth.Smooth(iter); } else if (strcmp(method, "PlaneFit") == 0) { @@ -1793,18 +2038,21 @@ PyObject* MeshPy::smooth(PyObject *args, PyObject *kwds) else { throw Py::ValueError("No such smoothing algorithm"); } - } PY_CATCH; + } + PY_CATCH; Py_Return; } -PyObject* MeshPy::decimate(PyObject *args) +PyObject* MeshPy::decimate(PyObject* args) { float fTol, fRed; - if (PyArg_ParseTuple(args, "ff", &fTol,&fRed)) { - PY_TRY { + if (PyArg_ParseTuple(args, "ff", &fTol, &fRed)) { + PY_TRY + { getMeshObjectPtr()->decimate(fTol, fRed); - } PY_CATCH; + } + PY_CATCH; Py_Return; } @@ -1812,32 +2060,35 @@ PyObject* MeshPy::decimate(PyObject *args) PyErr_Clear(); int targetSize; if (PyArg_ParseTuple(args, "i", &targetSize)) { - PY_TRY { + PY_TRY + { getMeshObjectPtr()->decimate(targetSize); - } PY_CATCH; + } + PY_CATCH; Py_Return; } - PyErr_SetString(PyExc_ValueError, "decimate(tolerance=float, reduction=float) or decimate(targetSize=int)"); + PyErr_SetString(PyExc_ValueError, + "decimate(tolerance=float, reduction=float) or decimate(targetSize=int)"); return nullptr; } -PyObject* MeshPy::nearestFacetOnRay(PyObject *args) +PyObject* MeshPy::nearestFacetOnRay(PyObject* args) { PyObject* pnt_p; PyObject* dir_p; double maxAngle = MeshCore::Mathd::PI; - if (!PyArg_ParseTuple(args, "OO|d", &pnt_p, &dir_p, &maxAngle)) + if (!PyArg_ParseTuple(args, "OO|d", &pnt_p, &dir_p, &maxAngle)) { return nullptr; + } try { Py::Vector pnt_t(pnt_p, false); Py::Vector dir_t(dir_p, false); Py::Dict dict; - MeshObject::TRay ray = std::make_pair(pnt_t.toVector(), - dir_t.toVector()); + MeshObject::TRay ray = std::make_pair(pnt_t.toVector(), dir_t.toVector()); MeshObject::TFaceSection output; if (getMeshObjectPtr()->nearestFacetOnRay(ray, maxAngle, output)) { Py::Tuple tuple(3); @@ -1854,19 +2105,20 @@ PyObject* MeshPy::nearestFacetOnRay(PyObject *args) } } -PyObject* MeshPy::getPlanarSegments(PyObject *args) +PyObject* MeshPy::getPlanarSegments(PyObject* args) { float dev; - unsigned long minFacets=0; - if (!PyArg_ParseTuple(args, "f|k",&dev,&minFacets)) + unsigned long minFacets = 0; + if (!PyArg_ParseTuple(args, "f|k", &dev, &minFacets)) { return nullptr; + } Mesh::MeshObject* mesh = getMeshObjectPtr(); - std::vector segments = mesh->getSegmentsOfType - (Mesh::MeshObject::PLANE, dev, minFacets); + std::vector segments = + mesh->getSegmentsOfType(Mesh::MeshObject::PLANE, dev, minFacets); Py::List s; - for (const auto & segment : segments) { + for (const auto& segment : segments) { const std::vector& segm = segment.getIndices(); Py::List ary; for (FacetIndex jt : segm) { @@ -1878,13 +2130,14 @@ PyObject* MeshPy::getPlanarSegments(PyObject *args) return Py::new_reference_to(s); } -PyObject* MeshPy::getSegmentsOfType(PyObject *args) +PyObject* MeshPy::getSegmentsOfType(PyObject* args) { char* type; float dev; - unsigned long minFacets=0; - if (!PyArg_ParseTuple(args, "sf|k",&type,&dev,&minFacets)) + unsigned long minFacets = 0; + if (!PyArg_ParseTuple(args, "sf|k", &type, &dev, &minFacets)) { return nullptr; + } Mesh::MeshObject::GeometryType geoType; if (strcmp(type, "Plane") == 0) { @@ -1902,11 +2155,10 @@ PyObject* MeshPy::getSegmentsOfType(PyObject *args) } Mesh::MeshObject* mesh = getMeshObjectPtr(); - std::vector segments = mesh->getSegmentsOfType - (geoType, dev, minFacets); + std::vector segments = mesh->getSegmentsOfType(geoType, dev, minFacets); Py::List s; - for (const auto & segment : segments) { + for (const auto& segment : segments) { const std::vector& segm = segment.getIndices(); Py::List ary; for (FacetIndex jt : segm) { @@ -1918,11 +2170,12 @@ PyObject* MeshPy::getSegmentsOfType(PyObject *args) return Py::new_reference_to(s); } -PyObject* MeshPy::getSegmentsByCurvature(PyObject *args) +PyObject* MeshPy::getSegmentsByCurvature(PyObject* args) { PyObject* l; - if (!PyArg_ParseTuple(args, "O",&l)) + if (!PyArg_ParseTuple(args, "O", &l)) { return nullptr; + } const MeshCore::MeshKernel& kernel = getMeshObjectPtr()->getKernel(); MeshCore::MeshSegmentAlgorithm finder(kernel); @@ -1938,15 +2191,21 @@ PyObject* MeshPy::getSegmentsByCurvature(PyObject *args) float tol1 = (float)Py::Float(t[2]); float tol2 = (float)Py::Float(t[3]); int num = (int)Py::Long(t[4]); - segm.emplace_back(std::make_shared(meshCurv.GetCurvature(), num, tol1, tol2, c1, c2)); + segm.emplace_back( + std::make_shared(meshCurv.GetCurvature(), + num, + tol1, + tol2, + c1, + c2)); } finder.FindSegments(segm); Py::List list; - for (const auto & segmIt : segm) { + for (const auto& segmIt : segm) { const std::vector& data = segmIt->GetSegments(); - for (const auto & it : data) { + for (const auto& it : data) { Py::List ary; for (FacetIndex jt : it) { ary.append(Py::Long(int(jt))); @@ -1960,8 +2219,9 @@ PyObject* MeshPy::getSegmentsByCurvature(PyObject *args) PyObject* MeshPy::getCurvaturePerVertex(PyObject* args) { - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, "")) { return nullptr; + } const MeshCore::MeshKernel& kernel = getMeshObjectPtr()->getKernel(); MeshCore::MeshCurvature meshCurv(kernel); @@ -2014,7 +2274,7 @@ Py::Float MeshPy::getVolume() const return Py::Float(getMeshObjectPtr()->getVolume()); } -PyObject *MeshPy::getCustomAttributes(const char* /*attr*/) const +PyObject* MeshPy::getCustomAttributes(const char* /*attr*/) const { return nullptr; } @@ -2027,10 +2287,12 @@ int MeshPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) Py::List MeshPy::getPoints() const { Py::List PointList; - unsigned int Index=0; + unsigned int Index = 0; MeshObject* mesh = getMeshObjectPtr(); - for (MeshObject::const_point_iterator it = mesh->points_begin(); it != mesh->points_end(); ++it) { - PointList.append(Py::Object(new MeshPointPy(new MeshPoint(*it,getMeshObjectPtr(),Index++)), true)); + for (MeshObject::const_point_iterator it = mesh->points_begin(); it != mesh->points_end(); + ++it) { + PointList.append( + Py::Object(new MeshPointPy(new MeshPoint(*it, getMeshObjectPtr(), Index++)), true)); } return PointList; } @@ -2039,7 +2301,8 @@ Py::List MeshPy::getFacets() const { Py::List FacetList; MeshObject* mesh = getMeshObjectPtr(); - for (MeshObject::const_facet_iterator it = mesh->facets_begin(); it != mesh->facets_end(); ++it) { + for (MeshObject::const_facet_iterator it = mesh->facets_begin(); it != mesh->facets_end(); + ++it) { FacetList.append(Py::Object(new FacetPy(new Facet(*it)), true)); } return FacetList; @@ -2052,19 +2315,18 @@ Py::Tuple MeshPy::getTopology() const getMeshObjectPtr()->getFaces(Points, Facets, 0.0); Py::Tuple tuple(2); Py::List vertex; - for (const auto & Point : Points) + for (const auto& Point : Points) { vertex.append(Py::asObject(new Base::VectorPy(Point))); + } tuple.setItem(0, vertex); Py::List facet; for (auto it : Facets) { Py::Tuple f(3); - f.setItem(0,Py::Long((int)it.I1)); - f.setItem(1,Py::Long((int)it.I2)); - f.setItem(2,Py::Long((int)it.I3)); + f.setItem(0, Py::Long((int)it.I1)); + f.setItem(1, Py::Long((int)it.I2)); + f.setItem(2, Py::Long((int)it.I3)); facet.append(f); } tuple.setItem(1, facet); return tuple; } - - diff --git a/src/Mod/Mesh/App/MeshTestsApp.py b/src/Mod/Mesh/App/MeshTestsApp.py index ba34ba2574..9fb0afe095 100644 --- a/src/Mod/Mesh/App/MeshTestsApp.py +++ b/src/Mod/Mesh/App/MeshTestsApp.py @@ -11,6 +11,7 @@ import FreeCAD, unittest, Mesh import MeshEnums from FreeCAD import Base import time, tempfile, math + # http://python-kurs.eu/threads.php try: import _thread as thread @@ -19,9 +20,9 @@ except Exception: from os.path import join -#--------------------------------------------------------------------------- +# --------------------------------------------------------------------------- # define the functions to test the FreeCAD mesh module -#--------------------------------------------------------------------------- +# --------------------------------------------------------------------------- class MeshTopoTestCases(unittest.TestCase): @@ -30,13 +31,12 @@ class MeshTopoTestCases(unittest.TestCase): self.planarMesh = [] for x in range(3): for y in range(3): - self.planarMesh.append( [0.0 + x, 0.0 + y,0.0000] ) - self.planarMesh.append( [1.0 + x, 1.0 + y,0.0000] ) - self.planarMesh.append( [0.0 + x, 1.0 + y,0.0000] ) - self.planarMesh.append( [0.0 + x, 0.0 + y,0.0000] ) - self.planarMesh.append( [1.0 + x, 0.0 + y,0.0000] ) - self.planarMesh.append( [1.0 + x, 1.0 + y,0.0000] ) - + self.planarMesh.append([0.0 + x, 0.0 + y, 0.0000]) + self.planarMesh.append([1.0 + x, 1.0 + y, 0.0000]) + self.planarMesh.append([0.0 + x, 1.0 + y, 0.0000]) + self.planarMesh.append([0.0 + x, 0.0 + y, 0.0000]) + self.planarMesh.append([1.0 + x, 0.0 + y, 0.0000]) + self.planarMesh.append([1.0 + x, 1.0 + y, 0.0000]) def testCollapseFacetsSingle(self): for i in range(18): @@ -51,6 +51,7 @@ class MeshTopoTestCases(unittest.TestCase): planarMeshObject = Mesh.Mesh(self.planarMesh) planarMeshObject.collapseFacets(range(18)) + # fmt: off def testCorruptedFacet(self): v = FreeCAD.Vector mesh = Mesh.Mesh() @@ -89,6 +90,9 @@ class MeshTopoTestCases(unittest.TestCase): self.assertEqual(mesh.CountFacets, 5) +# fmt: on + + class MeshSplitTestCases(unittest.TestCase): def setUp(self): self.mesh = Mesh.createBox(1.0, 1.0, 1.0) @@ -194,25 +198,31 @@ class MeshSplitTestCases(unittest.TestCase): self.assertTrue(self.mesh.isSolid()) def testFindNearest(self): - self.assertEqual(len(self.mesh.nearestFacetOnRay((-2,2,-6),(0,0,1))), 0) - self.assertEqual(len(self.mesh.nearestFacetOnRay((0.5,0.5,0.5),(0,0,1))), 1) - self.assertEqual(len(self.mesh.nearestFacetOnRay((0.5,0.5,0.5),(0,0,1),-math.pi/2)), 0) - self.assertEqual(len(self.mesh.nearestFacetOnRay((0.2,0.1,0.2),(0,0, 1))), - len(self.mesh.nearestFacetOnRay((0.2,0.1,0.2),(0,0,-1)))) - self.assertEqual(len(self.mesh.nearestFacetOnRay((0.2,0.1,0.2),(0,0, 1), math.pi/2)), - len(self.mesh.nearestFacetOnRay((0.2,0.1,0.2),(0,0,-1), math.pi/2))) + self.assertEqual(len(self.mesh.nearestFacetOnRay((-2, 2, -6), (0, 0, 1))), 0) + self.assertEqual(len(self.mesh.nearestFacetOnRay((0.5, 0.5, 0.5), (0, 0, 1))), 1) + self.assertEqual( + len(self.mesh.nearestFacetOnRay((0.5, 0.5, 0.5), (0, 0, 1), -math.pi / 2)), 0 + ) + self.assertEqual( + len(self.mesh.nearestFacetOnRay((0.2, 0.1, 0.2), (0, 0, 1))), + len(self.mesh.nearestFacetOnRay((0.2, 0.1, 0.2), (0, 0, -1))), + ) + self.assertEqual( + len(self.mesh.nearestFacetOnRay((0.2, 0.1, 0.2), (0, 0, 1), math.pi / 2)), + len(self.mesh.nearestFacetOnRay((0.2, 0.1, 0.2), (0, 0, -1), math.pi / 2)), + ) # Apply placement to mesh - plm = Base.Placement(Base.Vector(1,2,3), Base.Rotation(1,1,1,1)) + plm = Base.Placement(Base.Vector(1, 2, 3), Base.Rotation(1, 1, 1, 1)) pnt = Base.Vector(0.5, 0.5, 0.5) vec = Base.Vector(0.0, 0.0, 1.0) self.mesh.Placement = plm - self.assertEqual(len(self.mesh.nearestFacetOnRay(pnt,vec)), 0) + self.assertEqual(len(self.mesh.nearestFacetOnRay(pnt, vec)), 0) # Apply the placement on the ray as well pnt = plm.multVec(pnt) vec = plm.Rotation.multVec(vec) - self.assertEqual(len(self.mesh.nearestFacetOnRay(pnt,vec)), 1) + self.assertEqual(len(self.mesh.nearestFacetOnRay(pnt, vec)), 1) def testForaminate(self): class FilterAngle: @@ -225,10 +235,17 @@ class MeshSplitTestCases(unittest.TestCase): angle = self.myMesh.Facets[item].Normal.getAngle(self.vec) return angle < self.limit - results = self.mesh.foraminate((0.0, 0.0, 0.0), (0,1,1)) - filtered_result = list(filter(FilterAngle(self.mesh, FreeCAD.Vector(0,1,1), math.pi/2).check_angle, results.keys())) + results = self.mesh.foraminate((0.0, 0.0, 0.0), (0, 1, 1)) + filtered_result = list( + filter( + FilterAngle(self.mesh, FreeCAD.Vector(0, 1, 1), math.pi / 2).check_angle, + results.keys(), + ) + ) - self.assertEqual(filtered_result, list(self.mesh.foraminate((0.0, 0.0, 0.0), (0,1,1), math.pi/2))) + self.assertEqual( + filtered_result, list(self.mesh.foraminate((0.0, 0.0, 0.0), (0, 1, 1), math.pi / 2)) + ) def testForaminatePlacement(self): pnt = Base.Vector(0.0, 0.0, 0.0) @@ -237,7 +254,7 @@ class MeshSplitTestCases(unittest.TestCase): self.assertEqual(len(results), 4) # Apply placement to mesh - plm = Base.Placement(Base.Vector(1,2,3), Base.Rotation(1,1,1,1)) + plm = Base.Placement(Base.Vector(1, 2, 3), Base.Rotation(1, 1, 1, 1)) self.mesh.Placement = plm self.assertEqual(len(self.mesh.foraminate(pnt, vec)), 0) @@ -248,47 +265,46 @@ class MeshSplitTestCases(unittest.TestCase): self.assertEqual(len(results2), 4) self.assertEqual(list(results), list(results2)) + class MeshGeoTestCases(unittest.TestCase): def setUp(self): # set up a planar face with 2 triangles self.planarMesh = [] - def testIntersection(self): - self.planarMesh.append( [0.9961,1.5413,4.3943] ) - self.planarMesh.append( [9.4796,10.024,-3.0937] ) - self.planarMesh.append( [1.4308,11.3841,2.6829] ) - self.planarMesh.append( [2.6493,2.2536,3.0679] ) - self.planarMesh.append( [13.1126,0.4857,-4.4417] ) - self.planarMesh.append( [10.2410,8.9040,-3.5002] ) + self.planarMesh.append([0.9961, 1.5413, 4.3943]) + self.planarMesh.append([9.4796, 10.024, -3.0937]) + self.planarMesh.append([1.4308, 11.3841, 2.6829]) + self.planarMesh.append([2.6493, 2.2536, 3.0679]) + self.planarMesh.append([13.1126, 0.4857, -4.4417]) + self.planarMesh.append([10.2410, 8.9040, -3.5002]) planarMeshObject = Mesh.Mesh(self.planarMesh) f1 = planarMeshObject.Facets[0] f2 = planarMeshObject.Facets[1] - res=f1.intersect(f2) + res = f1.intersect(f2) self.assertTrue(len(res) == 0) - def testIntersection2(self): - self.planarMesh.append( [-16.097176,-29.891157,15.987688] ) - self.planarMesh.append( [-16.176304,-29.859991,15.947966] ) - self.planarMesh.append( [-16.071451,-29.900553,15.912505] ) - self.planarMesh.append( [-16.092241,-29.893408,16.020439] ) - self.planarMesh.append( [-16.007210,-29.926180,15.967641] ) - self.planarMesh.append( [-16.064457,-29.904951,16.090832] ) + self.planarMesh.append([-16.097176, -29.891157, 15.987688]) + self.planarMesh.append([-16.176304, -29.859991, 15.947966]) + self.planarMesh.append([-16.071451, -29.900553, 15.912505]) + self.planarMesh.append([-16.092241, -29.893408, 16.020439]) + self.planarMesh.append([-16.007210, -29.926180, 15.967641]) + self.planarMesh.append([-16.064457, -29.904951, 16.090832]) planarMeshObject = Mesh.Mesh(self.planarMesh) f1 = planarMeshObject.Facets[0] f2 = planarMeshObject.Facets[1] # does definitely NOT intersect - res=f1.intersect(f2) + res = f1.intersect(f2) self.assertTrue(len(res) == 0) def testIntersectionOfTransformedMesh(self): - self.planarMesh.append( [0.0,10.0,10.0] ) - self.planarMesh.append( [10.0,0.0,10.0] ) - self.planarMesh.append( [10.0,10.0,10.0] ) - self.planarMesh.append( [6.0,8.0,10.0] ) - self.planarMesh.append( [16.0,8.0,10.0] ) - self.planarMesh.append( [6.0,18.0,10.0] ) + self.planarMesh.append([0.0, 10.0, 10.0]) + self.planarMesh.append([10.0, 0.0, 10.0]) + self.planarMesh.append([10.0, 10.0, 10.0]) + self.planarMesh.append([6.0, 8.0, 10.0]) + self.planarMesh.append([16.0, 8.0, 10.0]) + self.planarMesh.append([6.0, 18.0, 10.0]) planarMeshObject = Mesh.Mesh(self.planarMesh) mat = Base.Matrix() @@ -299,16 +315,16 @@ class MeshGeoTestCases(unittest.TestCase): f1 = planarMeshObject.Facets[0] f2 = planarMeshObject.Facets[1] - res=f1.intersect(f2) + res = f1.intersect(f2) self.assertEqual(len(res), 2) def testIntersectionOfParallelTriangles(self): - self.planarMesh.append( [0.0,10.0,10.0] ) - self.planarMesh.append( [10.0,0.0,10.0] ) - self.planarMesh.append( [10.0,10.0,10.0] ) - self.planarMesh.append( [6.0,8.0,10.1] ) - self.planarMesh.append( [16.0,8.0,10.1] ) - self.planarMesh.append( [6.0,18.0,10.1] ) + self.planarMesh.append([0.0, 10.0, 10.0]) + self.planarMesh.append([10.0, 0.0, 10.0]) + self.planarMesh.append([10.0, 10.0, 10.0]) + self.planarMesh.append([6.0, 8.0, 10.1]) + self.planarMesh.append([16.0, 8.0, 10.1]) + self.planarMesh.append([6.0, 18.0, 10.1]) planarMeshObject = Mesh.Mesh(self.planarMesh) mat = Base.Matrix() @@ -319,16 +335,16 @@ class MeshGeoTestCases(unittest.TestCase): f1 = planarMeshObject.Facets[0] f2 = planarMeshObject.Facets[1] - res=f1.intersect(f2) + res = f1.intersect(f2) self.assertTrue(len(res) == 0) def testIntersectionOnEdge(self): - self.planarMesh.append( [5.0, -1.9371663331985474, 0.49737977981567383] ) - self.planarMesh.append( [4.0, -1.9371663331985474, 0.49737977981567383] ) - self.planarMesh.append( [5.0, -1.9842294454574585, 0.25066646933555603] ) - self.planarMesh.append( [4.6488823890686035, -1.7827962636947632, 0.4577442705631256] ) - self.planarMesh.append( [4.524135112762451, -2.0620131492614746, 0.5294350385665894] ) - self.planarMesh.append( [4.6488823890686035, -1.8261089324951172, 0.23069120943546295] ) + self.planarMesh.append([5.0, -1.9371663331985474, 0.49737977981567383]) + self.planarMesh.append([4.0, -1.9371663331985474, 0.49737977981567383]) + self.planarMesh.append([5.0, -1.9842294454574585, 0.25066646933555603]) + self.planarMesh.append([4.6488823890686035, -1.7827962636947632, 0.4577442705631256]) + self.planarMesh.append([4.524135112762451, -2.0620131492614746, 0.5294350385665894]) + self.planarMesh.append([4.6488823890686035, -1.8261089324951172, 0.23069120943546295]) planarMeshObject = Mesh.Mesh(self.planarMesh) f1 = planarMeshObject.Facets[0] f2 = planarMeshObject.Facets[1] @@ -336,12 +352,12 @@ class MeshGeoTestCases(unittest.TestCase): self.assertEqual(len(res), 2) def testIntersectionCoplanar(self): - self.planarMesh.append( [0.,10.,10.] ) - self.planarMesh.append( [10.,0.,10.] ) - self.planarMesh.append( [10.,10.,10.] ) - self.planarMesh.append( [6.,8.,10.] ) - self.planarMesh.append( [16.,8.,10.] ) - self.planarMesh.append( [6.,18.,10.] ) + self.planarMesh.append([0.0, 10.0, 10.0]) + self.planarMesh.append([10.0, 0.0, 10.0]) + self.planarMesh.append([10.0, 10.0, 10.0]) + self.planarMesh.append([6.0, 8.0, 10.0]) + self.planarMesh.append([16.0, 8.0, 10.0]) + self.planarMesh.append([6.0, 18.0, 10.0]) planarMeshObject = Mesh.Mesh(self.planarMesh) f1 = planarMeshObject.Facets[0] f2 = planarMeshObject.Facets[1] @@ -349,12 +365,12 @@ class MeshGeoTestCases(unittest.TestCase): self.assertTrue(len(res) == 2) def testIntersectionOverlap(self): - self.planarMesh.append( [0.,0.,0.] ) - self.planarMesh.append( [5.,0.,0.] ) - self.planarMesh.append( [8.,5.,0.] ) - self.planarMesh.append( [4.,0.,0.] ) - self.planarMesh.append( [10.,0.,0.] ) - self.planarMesh.append( [9.,5.,0.] ) + self.planarMesh.append([0.0, 0.0, 0.0]) + self.planarMesh.append([5.0, 0.0, 0.0]) + self.planarMesh.append([8.0, 5.0, 0.0]) + self.planarMesh.append([4.0, 0.0, 0.0]) + self.planarMesh.append([10.0, 0.0, 0.0]) + self.planarMesh.append([9.0, 5.0, 0.0]) planarMeshObject = Mesh.Mesh(self.planarMesh) f1 = planarMeshObject.Facets[0] f2 = planarMeshObject.Facets[1] @@ -362,12 +378,12 @@ class MeshGeoTestCases(unittest.TestCase): self.assertTrue(len(res) == 2) def testIntersectionOfIntersectingEdges(self): - self.planarMesh.append( [0.,10.,10.] ) - self.planarMesh.append( [10.,0.,10.] ) - self.planarMesh.append( [10.,10.,10.] ) - self.planarMesh.append( [6.,8.,10.] ) - self.planarMesh.append( [16.,8.,10.] ) - self.planarMesh.append( [6.,18.,10.] ) + self.planarMesh.append([0.0, 10.0, 10.0]) + self.planarMesh.append([10.0, 0.0, 10.0]) + self.planarMesh.append([10.0, 10.0, 10.0]) + self.planarMesh.append([6.0, 8.0, 10.0]) + self.planarMesh.append([16.0, 8.0, 10.0]) + self.planarMesh.append([6.0, 18.0, 10.0]) planarMeshObject = Mesh.Mesh(self.planarMesh) edge1 = planarMeshObject.Facets[0].getEdge(2) @@ -379,12 +395,12 @@ class MeshGeoTestCases(unittest.TestCase): self.assertEqual(res[0][2], 10.0) def testIntersectionOfParallelEdges(self): - self.planarMesh.append( [0.,10.,10.] ) - self.planarMesh.append( [10.,0.,10.] ) - self.planarMesh.append( [10.,10.,10.] ) - self.planarMesh.append( [6.,8.,10.] ) - self.planarMesh.append( [16.,8.,10.] ) - self.planarMesh.append( [6.,18.,10.] ) + self.planarMesh.append([0.0, 10.0, 10.0]) + self.planarMesh.append([10.0, 0.0, 10.0]) + self.planarMesh.append([10.0, 10.0, 10.0]) + self.planarMesh.append([6.0, 8.0, 10.0]) + self.planarMesh.append([16.0, 8.0, 10.0]) + self.planarMesh.append([6.0, 18.0, 10.0]) planarMeshObject = Mesh.Mesh(self.planarMesh) edge1 = planarMeshObject.Facets[0].getEdge(2) @@ -393,12 +409,12 @@ class MeshGeoTestCases(unittest.TestCase): self.assertTrue(len(res) == 0) def testIntersectionOfCollinearEdges(self): - self.planarMesh.append( [0.,0.,0.] ) - self.planarMesh.append( [6.,0.,0.] ) - self.planarMesh.append( [3.,4.,0.] ) - self.planarMesh.append( [7.,0.,0.] ) - self.planarMesh.append( [13.,0.,0.] ) - self.planarMesh.append( [10.,4.,0.] ) + self.planarMesh.append([0.0, 0.0, 0.0]) + self.planarMesh.append([6.0, 0.0, 0.0]) + self.planarMesh.append([3.0, 4.0, 0.0]) + self.planarMesh.append([7.0, 0.0, 0.0]) + self.planarMesh.append([13.0, 0.0, 0.0]) + self.planarMesh.append([10.0, 4.0, 0.0]) planarMeshObject = Mesh.Mesh(self.planarMesh) edge1 = planarMeshObject.Facets[0].getEdge(0) @@ -407,12 +423,12 @@ class MeshGeoTestCases(unittest.TestCase): self.assertTrue(len(res) == 0) def testIntersectionOfWarpedEdges(self): - self.planarMesh.append( [0.,0.,0.] ) - self.planarMesh.append( [6.,0.,0.] ) - self.planarMesh.append( [3.,4.,0.] ) - self.planarMesh.append( [2.,2.,1.] ) - self.planarMesh.append( [8.,2.,1.] ) - self.planarMesh.append( [5.,6.,1.] ) + self.planarMesh.append([0.0, 0.0, 0.0]) + self.planarMesh.append([6.0, 0.0, 0.0]) + self.planarMesh.append([3.0, 4.0, 0.0]) + self.planarMesh.append([2.0, 2.0, 1.0]) + self.planarMesh.append([8.0, 2.0, 1.0]) + self.planarMesh.append([5.0, 6.0, 1.0]) planarMeshObject = Mesh.Mesh(self.planarMesh) edge1 = planarMeshObject.Facets[0].getEdge(1) @@ -473,84 +489,91 @@ class PivyTestCases(unittest.TestCase): def testRayPick(self): if not FreeCAD.GuiUp: return - self.planarMesh.append( [-16.097176,-29.891157,15.987688] ) - self.planarMesh.append( [-16.176304,-29.859991,15.947966] ) - self.planarMesh.append( [-16.071451,-29.900553,15.912505] ) - self.planarMesh.append( [-16.092241,-29.893408,16.020439] ) - self.planarMesh.append( [-16.007210,-29.926180,15.967641] ) - self.planarMesh.append( [-16.064457,-29.904951,16.090832] ) + self.planarMesh.append([-16.097176, -29.891157, 15.987688]) + self.planarMesh.append([-16.176304, -29.859991, 15.947966]) + self.planarMesh.append([-16.071451, -29.900553, 15.912505]) + self.planarMesh.append([-16.092241, -29.893408, 16.020439]) + self.planarMesh.append([-16.007210, -29.926180, 15.967641]) + self.planarMesh.append([-16.064457, -29.904951, 16.090832]) planarMeshObject = Mesh.Mesh(self.planarMesh) - from pivy import coin; import FreeCADGui + from pivy import coin + import FreeCADGui + Mesh.show(planarMeshObject) - view=FreeCADGui.ActiveDocument.ActiveView.getViewer() - rp=coin.SoRayPickAction(view.getSoRenderManager().getViewportRegion()) - rp.setRay(coin.SbVec3f(-16.05,16.0,16.0),coin.SbVec3f(0,-1,0)) + view = FreeCADGui.ActiveDocument.ActiveView.getViewer() + rp = coin.SoRayPickAction(view.getSoRenderManager().getViewportRegion()) + rp.setRay(coin.SbVec3f(-16.05, 16.0, 16.0), coin.SbVec3f(0, -1, 0)) rp.apply(view.getSoRenderManager().getSceneGraph()) - pp=rp.getPickedPoint() + pp = rp.getPickedPoint() self.assertTrue(pp is not None) - det=pp.getDetail() + det = pp.getDetail() self.assertTrue(det.getTypeId() == coin.SoFaceDetail.getClassTypeId()) - det=coin.cast(det, det.getTypeId().getName().getString()) + det = coin.cast(det, det.getTypeId().getName().getString()) self.assertTrue(det.getFaceIndex() == 1) def testPrimitiveCount(self): if not FreeCAD.GuiUp: return - self.planarMesh.append( [-16.097176,-29.891157,15.987688] ) - self.planarMesh.append( [-16.176304,-29.859991,15.947966] ) - self.planarMesh.append( [-16.071451,-29.900553,15.912505] ) - self.planarMesh.append( [-16.092241,-29.893408,16.020439] ) - self.planarMesh.append( [-16.007210,-29.926180,15.967641] ) - self.planarMesh.append( [-16.064457,-29.904951,16.090832] ) + self.planarMesh.append([-16.097176, -29.891157, 15.987688]) + self.planarMesh.append([-16.176304, -29.859991, 15.947966]) + self.planarMesh.append([-16.071451, -29.900553, 15.912505]) + self.planarMesh.append([-16.092241, -29.893408, 16.020439]) + self.planarMesh.append([-16.007210, -29.926180, 15.967641]) + self.planarMesh.append([-16.064457, -29.904951, 16.090832]) planarMeshObject = Mesh.Mesh(self.planarMesh) - from pivy import coin; import FreeCADGui + from pivy import coin + import FreeCADGui + Mesh.show(planarMeshObject) - view=FreeCADGui.ActiveDocument.ActiveView + view = FreeCADGui.ActiveDocument.ActiveView view.setAxisCross(False) - pc=coin.SoGetPrimitiveCountAction() + pc = coin.SoGetPrimitiveCountAction() pc.apply(view.getSceneGraph()) self.assertTrue(pc.getTriangleCount() == 2) - #self.assertTrue(pc.getPointCount() == 6) + # self.assertTrue(pc.getPointCount() == 6) def tearDown(self): - #closing doc + # closing doc FreeCAD.closeDocument("MeshTest") + # Threads -def loadFile(name): - #lock.acquire() - mesh=Mesh.Mesh() - #FreeCAD.Console.PrintMessage("Create mesh instance\n") - #lock.release() - mesh.read(name) - #FreeCAD.Console.PrintMessage("Mesh loaded successfully.\n") -def createMesh(r,s): - #FreeCAD.Console.PrintMessage("Create sphere (%s,%s)...\n"%(r,s)) - mesh=Mesh.createSphere(r,s) - #FreeCAD.Console.PrintMessage("... destroy sphere\n") +def loadFile(name): + # lock.acquire() + mesh = Mesh.Mesh() + # FreeCAD.Console.PrintMessage("Create mesh instance\n") + # lock.release() + mesh.read(name) + # FreeCAD.Console.PrintMessage("Mesh loaded successfully.\n") + + +def createMesh(r, s): + # FreeCAD.Console.PrintMessage("Create sphere (%s,%s)...\n"%(r,s)) + mesh = Mesh.createSphere(r, s) + # FreeCAD.Console.PrintMessage("... destroy sphere\n") + class LoadMeshInThreadsCases(unittest.TestCase): - def setUp(self): pass def testSphereMesh(self): - for i in range(6,8): - thread.start_new(createMesh,(10.0,(i+1)*20)) + for i in range(6, 8): + thread.start_new(createMesh, (10.0, (i + 1) * 20)) time.sleep(10) def testLoadMesh(self): - mesh=Mesh.createSphere(10.0,100) # a fine sphere - name=tempfile.gettempdir() + os.sep + "mesh.stl" + mesh = Mesh.createSphere(10.0, 100) # a fine sphere + name = tempfile.gettempdir() + os.sep + "mesh.stl" mesh.write(name) - #FreeCAD.Console.PrintMessage("Write mesh to %s\n"%(name)) - #lock=thread.allocate_lock() + # FreeCAD.Console.PrintMessage("Write mesh to %s\n"%(name)) + # lock=thread.allocate_lock() for i in range(2): - thread.start_new(loadFile,(name,)) + thread.start_new(loadFile, (name,)) time.sleep(1) def tearDown(self): @@ -563,54 +586,54 @@ class PolynomialFitCases(unittest.TestCase): def testFitGood(self): # symmetric - v=[] - v.append(FreeCAD.Vector(0,0,0.0)) - v.append(FreeCAD.Vector(1,0,0.5)) - v.append(FreeCAD.Vector(2,0,0.0)) - v.append(FreeCAD.Vector(0,1,0.5)) - v.append(FreeCAD.Vector(1,1,1.0)) - v.append(FreeCAD.Vector(2,1,0.5)) - v.append(FreeCAD.Vector(0,2,0.0)) - v.append(FreeCAD.Vector(1,2,0.5)) - v.append(FreeCAD.Vector(2,2,0.0)) + v = [] + v.append(FreeCAD.Vector(0, 0, 0.0)) + v.append(FreeCAD.Vector(1, 0, 0.5)) + v.append(FreeCAD.Vector(2, 0, 0.0)) + v.append(FreeCAD.Vector(0, 1, 0.5)) + v.append(FreeCAD.Vector(1, 1, 1.0)) + v.append(FreeCAD.Vector(2, 1, 0.5)) + v.append(FreeCAD.Vector(0, 2, 0.0)) + v.append(FreeCAD.Vector(1, 2, 0.5)) + v.append(FreeCAD.Vector(2, 2, 0.0)) d = Mesh.polynomialFit(v) c = d["Coefficients"] - #print ("Polynomial: f(x,y)=%f*x^2%+f*y^2%+f*x*y%+f*x%+f*y%+f" % (c[0],c[1],c[2],c[3],c[4],c[5])) + # print ("Polynomial: f(x,y)=%f*x^2%+f*y^2%+f*x*y%+f*x%+f*y%+f" % (c[0],c[1],c[2],c[3],c[4],c[5])) for i in d["Residuals"]: - self.assertTrue(math.fabs(i) < 0.0001, "Too high residual %f" % math.fabs(i)) + self.assertTrue(math.fabs(i) < 0.0001, "Too high residual %f" % math.fabs(i)) def testFitExact(self): # symmetric - v=[] - v.append(FreeCAD.Vector(0,0,0.0)) - v.append(FreeCAD.Vector(1,0,0.0)) - v.append(FreeCAD.Vector(2,0,0.0)) - v.append(FreeCAD.Vector(0,1,0.0)) - v.append(FreeCAD.Vector(1,1,1.0)) - v.append(FreeCAD.Vector(2,1,0.0)) + v = [] + v.append(FreeCAD.Vector(0, 0, 0.0)) + v.append(FreeCAD.Vector(1, 0, 0.0)) + v.append(FreeCAD.Vector(2, 0, 0.0)) + v.append(FreeCAD.Vector(0, 1, 0.0)) + v.append(FreeCAD.Vector(1, 1, 1.0)) + v.append(FreeCAD.Vector(2, 1, 0.0)) d = Mesh.polynomialFit(v) c = d["Coefficients"] - #print ("Polynomial: f(x,y)=%f*x^2%+f*y^2%+f*x*y%+f*x%+f*y%+f" % (c[0],c[1],c[2],c[3],c[4],c[5])) + # print ("Polynomial: f(x,y)=%f*x^2%+f*y^2%+f*x*y%+f*x%+f*y%+f" % (c[0],c[1],c[2],c[3],c[4],c[5])) for i in d["Residuals"]: - self.assertTrue(math.fabs(i) < 0.0001, "Too high residual %f" % math.fabs(i)) + self.assertTrue(math.fabs(i) < 0.0001, "Too high residual %f" % math.fabs(i)) def testFitBad(self): # symmetric - v=[] - v.append(FreeCAD.Vector(0,0,0.0)) - v.append(FreeCAD.Vector(1,0,0.0)) - v.append(FreeCAD.Vector(2,0,0.0)) - v.append(FreeCAD.Vector(0,1,0.0)) - v.append(FreeCAD.Vector(1,1,1.0)) - v.append(FreeCAD.Vector(2,1,0.0)) - v.append(FreeCAD.Vector(0,2,0.0)) - v.append(FreeCAD.Vector(1,2,0.0)) - v.append(FreeCAD.Vector(2,2,0.0)) + v = [] + v.append(FreeCAD.Vector(0, 0, 0.0)) + v.append(FreeCAD.Vector(1, 0, 0.0)) + v.append(FreeCAD.Vector(2, 0, 0.0)) + v.append(FreeCAD.Vector(0, 1, 0.0)) + v.append(FreeCAD.Vector(1, 1, 1.0)) + v.append(FreeCAD.Vector(2, 1, 0.0)) + v.append(FreeCAD.Vector(0, 2, 0.0)) + v.append(FreeCAD.Vector(1, 2, 0.0)) + v.append(FreeCAD.Vector(2, 2, 0.0)) d = Mesh.polynomialFit(v) c = d["Coefficients"] - #print ("Polynomial: f(x,y)=%f*x^2%+f*y^2%+f*x*y%+f*x%+f*y%+f" % (c[0],c[1],c[2],c[3],c[4],c[5])) + # print ("Polynomial: f(x,y)=%f*x^2%+f*y^2%+f*x*y%+f*x%+f*y%+f" % (c[0],c[1],c[2],c[3],c[4],c[5])) for i in d["Residuals"]: - self.assertFalse(math.fabs(i) < 0.0001, "Residual %f must be higher" % math.fabs(i)) + self.assertFalse(math.fabs(i) < 0.0001, "Residual %f must be higher" % math.fabs(i)) def tearDown(self): pass @@ -622,27 +645,28 @@ class NastranReader(unittest.TestCase): def testEightCharGRIDElement(self): m = Mesh.read(f"{self.test_dir}/NASTRAN_Test_GRID_CQUAD4.bdf") - self.assertEqual(m.CountPoints,10) - self.assertEqual(m.CountFacets,8) # Quads split into two triangles + self.assertEqual(m.CountPoints, 10) + self.assertEqual(m.CountFacets, 8) # Quads split into two triangles def testDelimitedGRIDElement(self): m = Mesh.read(f"{self.test_dir}/NASTRAN_Test_Delimited_GRID_CQUAD4.bdf") - self.assertEqual(m.CountPoints,10) - self.assertEqual(m.CountFacets,8) # Quads split into two triangles + self.assertEqual(m.CountPoints, 10) + self.assertEqual(m.CountFacets, 8) # Quads split into two triangles def testSixteenCharGRIDElement(self): m = Mesh.read(f"{self.test_dir}/NASTRAN_Test_GRIDSTAR_CQUAD4.bdf") - self.assertEqual(m.CountPoints,4) - self.assertEqual(m.CountFacets,2) # Quads split into two triangles + self.assertEqual(m.CountPoints, 4) + self.assertEqual(m.CountFacets, 2) # Quads split into two triangles def testCTRIA3Element(self): m = Mesh.read(f"{self.test_dir}/NASTRAN_Test_GRID_CTRIA3.bdf") - self.assertEqual(m.CountPoints,3) - self.assertEqual(m.CountFacets,1) + self.assertEqual(m.CountPoints, 3) + self.assertEqual(m.CountFacets, 1) def tearDown(self): pass + class MeshSubElement(unittest.TestCase): def setUp(self): self.mesh = Mesh.createBox(1.0, 1.0, 1.0) @@ -683,6 +707,7 @@ class MeshSubElement(unittest.TestCase): def tearDown(self): pass + class MeshProperty(unittest.TestCase): def setUp(self): self.doc = FreeCAD.newDocument("MeshTest") @@ -695,12 +720,12 @@ class MeshProperty(unittest.TestCase): mesh.Mesh = Mesh.createBox(1.0, 1.0, 1.0) len1 = int(mesh.Mesh.CountFacets / 2) len2 = int(mesh.Mesh.CountFacets - len1) - material = {"transparency" : [0.2] * len1 + [0.8] * len2} + material = {"transparency": [0.2] * len1 + [0.8] * len2} material["binding"] = MeshEnums.Binding.PER_FACE - material["ambientColor"] = [(1,0,0)] * (len1 + len2) - material["diffuseColor"] = [(0,1,0)] * (len1 + len2) - material["specularColor"] = [(0,0,1)] * (len1 + len2) - material["emissiveColor"] = [(1,1,1)] * (len1 + len2) + material["ambientColor"] = [(1, 0, 0)] * (len1 + len2) + material["diffuseColor"] = [(0, 1, 0)] * (len1 + len2) + material["specularColor"] = [(0, 0, 1)] * (len1 + len2) + material["emissiveColor"] = [(1, 1, 1)] * (len1 + len2) material["shininess"] = [0.3] * (len1 + len2) mesh.addProperty("Mesh::PropertyMaterial", "Material") @@ -722,4 +747,3 @@ class MeshProperty(unittest.TestCase): self.assertEqual(len(material2["emissiveColor"]), len1 + len2) self.assertEqual(len(material2["shininess"]), len1 + len2) self.assertEqual(len(material2["transparency"]), len1 + len2) - diff --git a/src/Mod/Mesh/App/MeshTexture.cpp b/src/Mod/Mesh/App/MeshTexture.cpp index f0cfd6c338..3e657388c9 100644 --- a/src/Mod/Mesh/App/MeshTexture.cpp +++ b/src/Mod/Mesh/App/MeshTexture.cpp @@ -27,49 +27,60 @@ using namespace Mesh; -MeshTexture::MeshTexture(const Mesh::MeshObject& mesh, const MeshCore::Material &material) - : materialRefMesh(material) +MeshTexture::MeshTexture(const Mesh::MeshObject& mesh, const MeshCore::Material& material) + : materialRefMesh(material) { countPointsRefMesh = mesh.countPoints(); unsigned long countFacets = mesh.countFacets(); - if (material.binding == MeshCore::MeshIO::PER_VERTEX && material.diffuseColor.size() == countPointsRefMesh) { + if (material.binding == MeshCore::MeshIO::PER_VERTEX + && material.diffuseColor.size() == countPointsRefMesh) { binding = MeshCore::MeshIO::PER_VERTEX; kdTree = std::make_unique(mesh.getKernel().GetPoints()); } - else if (material.binding == MeshCore::MeshIO::PER_FACE && material.diffuseColor.size() == countFacets) { + else if (material.binding == MeshCore::MeshIO::PER_FACE + && material.diffuseColor.size() == countFacets) { binding = MeshCore::MeshIO::PER_FACE; kdTree = std::make_unique(mesh.getKernel().GetPoints()); refPnt2Fac = std::make_unique(mesh.getKernel()); } } -void MeshTexture::apply(const Mesh::MeshObject& mesh, const App::Color& defaultColor, MeshCore::Material &material) +void MeshTexture::apply(const Mesh::MeshObject& mesh, + const App::Color& defaultColor, + MeshCore::Material& material) { apply(mesh, true, defaultColor, -1.0f, material); } -void MeshTexture::apply(const Mesh::MeshObject& mesh, const App::Color& defaultColor, float max_dist, MeshCore::Material &material) +void MeshTexture::apply(const Mesh::MeshObject& mesh, + const App::Color& defaultColor, + float max_dist, + MeshCore::Material& material) { apply(mesh, true, defaultColor, max_dist, material); } -void MeshTexture::apply(const Mesh::MeshObject& mesh, MeshCore::Material &material) +void MeshTexture::apply(const Mesh::MeshObject& mesh, MeshCore::Material& material) { App::Color defaultColor; apply(mesh, false, defaultColor, -1.0f, material); } -void MeshTexture::apply(const Mesh::MeshObject& mesh, float max_dist, MeshCore::Material &material) +void MeshTexture::apply(const Mesh::MeshObject& mesh, float max_dist, MeshCore::Material& material) { App::Color defaultColor; apply(mesh, false, defaultColor, max_dist, material); } -void MeshTexture::apply(const Mesh::MeshObject& mesh, bool addDefaultColor, const App::Color& defaultColor, - float max_dist, MeshCore::Material &material) +void MeshTexture::apply(const Mesh::MeshObject& mesh, + bool addDefaultColor, + const App::Color& defaultColor, + float max_dist, + MeshCore::Material& material) { - // copy the color values because the passed material could be the same instance as 'materialRefMesh' + // copy the color values because the passed material could be the same instance as + // 'materialRefMesh' std::vector textureColor = materialRefMesh.diffuseColor; material.diffuseColor.clear(); material.binding = MeshCore::MeshIO::OVERALL; @@ -82,7 +93,7 @@ void MeshTexture::apply(const Mesh::MeshObject& mesh, bool addDefaultColor, cons if (binding == MeshCore::MeshIO::PER_VERTEX) { diffuseColor.reserve(points.size()); - for (size_t index=0; index pointMap; pointMap.reserve(points.size()); - for (size_t index=0; index found = refPnt2Fac->GetIndices(index1, index2, index3); + if (index1 != MeshCore::POINT_INDEX_MAX && index2 != MeshCore::POINT_INDEX_MAX + && index3 != MeshCore::POINT_INDEX_MAX) { + std::vector found = + refPnt2Fac->GetIndices(index1, index2, index3); if (found.size() == 1) { diffuseColor.push_back(textureColor[found.front()]); } diff --git a/src/Mod/Mesh/App/MeshTexture.h b/src/Mod/Mesh/App/MeshTexture.h index 8b70efba38..bcc5dfc35b 100644 --- a/src/Mod/Mesh/App/MeshTexture.h +++ b/src/Mod/Mesh/App/MeshTexture.h @@ -46,35 +46,45 @@ public: /*! A mesh with material. The number of points or facets must match with the number of colors. */ - MeshTexture(const Mesh::MeshObject& mesh, const MeshCore::Material &material); + MeshTexture(const Mesh::MeshObject& mesh, const MeshCore::Material& material); /*! Find common points or facets of this to the original mesh. For points or facets that don't match \a defaultColor will be used instead, otherwise the color of the original material is used. */ - void apply(const Mesh::MeshObject& mesh, const App::Color& defaultColor, MeshCore::Material &material); + void apply(const Mesh::MeshObject& mesh, + const App::Color& defaultColor, + MeshCore::Material& material); /*! Find common points or facets of this to the original mesh. For points or facets that don't match \a defaultColor will be used instead, otherwise the color of the original material is used. */ - void apply(const Mesh::MeshObject& mesh, const App::Color& defaultColor, float max_dist, MeshCore::Material &material); + void apply(const Mesh::MeshObject& mesh, + const App::Color& defaultColor, + float max_dist, + MeshCore::Material& material); /*! - Find common points or facets of this to the original mesh and use the color of the original material. - If for a point of \a mesh no matching point of the original mesh can be found the texture mapping will - fail. + Find common points or facets of this to the original mesh and use the color of the original + material. If for a point of \a mesh no matching point of the original mesh can be found the + texture mapping will fail. */ - void apply(const Mesh::MeshObject& mesh, MeshCore::Material &material); + void apply(const Mesh::MeshObject& mesh, MeshCore::Material& material); /*! - Find common points or facets of this to the original mesh and use the color of the original material. - If for a point of \a mesh no matching point of the original mesh can be found the texture mapping will - fail. + Find common points or facets of this to the original mesh and use the color of the original + material. If for a point of \a mesh no matching point of the original mesh can be found the + texture mapping will fail. */ - void apply(const Mesh::MeshObject& mesh, float max_dist, MeshCore::Material &material); + void apply(const Mesh::MeshObject& mesh, float max_dist, MeshCore::Material& material); private: - void apply(const Mesh::MeshObject& mesh, bool addDefaultColor, const App::Color& defaultColor, float max_dist, MeshCore::Material &material); - PointIndex findIndex(const Base::Vector3f& p, float max_dist) const { + void apply(const Mesh::MeshObject& mesh, + bool addDefaultColor, + const App::Color& defaultColor, + float max_dist, + MeshCore::Material& material); + PointIndex findIndex(const Base::Vector3f& p, float max_dist) const + { if (max_dist < 0.0f) { return kdTree->FindExact(p); } @@ -86,13 +96,13 @@ private: } private: - const MeshCore::Material &materialRefMesh; + const MeshCore::Material& materialRefMesh; unsigned long countPointsRefMesh; std::unique_ptr kdTree; std::unique_ptr refPnt2Fac; MeshCore::MeshIO::Binding binding = MeshCore::MeshIO::OVERALL; }; -} // namespace Mesh +} // namespace Mesh -#endif // MESH_MESHTEXTURE_H +#endif // MESH_MESHTEXTURE_H diff --git a/src/Mod/Mesh/App/PreCompiled.cpp b/src/Mod/Mesh/App/PreCompiled.cpp index cd188de772..ccf2b83403 100644 --- a/src/Mod/Mesh/App/PreCompiled.cpp +++ b/src/Mod/Mesh/App/PreCompiled.cpp @@ -22,4 +22,3 @@ #include "PreCompiled.h" - diff --git a/src/Mod/Mesh/App/PreCompiled.h b/src/Mod/Mesh/App/PreCompiled.h index 9cce876f6d..b8f33e88c2 100644 --- a/src/Mod/Mesh/App/PreCompiled.h +++ b/src/Mod/Mesh/App/PreCompiled.h @@ -28,31 +28,31 @@ // point at which warnings of overly long specifiers disabled (needed for VC6) #ifdef _MSC_VER -# pragma warning( disable : 4251 ) -# pragma warning( disable : 4503 ) -# pragma warning( disable : 4275 ) -# pragma warning( disable : 4786 ) // specifier longer then 255 chars -# pragma warning( disable : 4661 ) // no suitable definition provided for explicit -#endif // template instantiation request +#pragma warning(disable : 4251) +#pragma warning(disable : 4503) +#pragma warning(disable : 4275) +#pragma warning(disable : 4786) // specifier longer then 255 chars +#pragma warning(disable : 4661) // no suitable definition provided for explicit +#endif // template instantiation request #ifdef _PreComp_ // standard -#include #include -#include #include +#include +#include #include #include #include #ifdef FC_USE_GTS -# include +#include #endif // STL #include -#include #include +#include #include #include #include @@ -66,26 +66,25 @@ #include #include #include -#include #include +#include // Xerces -#include -#include #include #include #include -#include #include #include +#include #include -#include -#include -#include #include #include +#include +#include +#include +#include +#include -#endif //_PreComp_ +#endif //_PreComp_ #endif - diff --git a/src/Mod/Mesh/App/Segment.cpp b/src/Mod/Mesh/App/Segment.cpp index 8c245fbe10..69b66112a4 100644 --- a/src/Mod/Mesh/App/Segment.cpp +++ b/src/Mod/Mesh/App/Segment.cpp @@ -22,32 +22,32 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include +#include +#include #endif -#include "Segment.h" #include "Mesh.h" #include "MeshPy.h" +#include "Segment.h" using namespace Mesh; Segment::Segment(const MeshObject* mesh, bool mod) - : _mesh(mesh) - , _save(false) - , _modifykernel(mod) -{ -} + : _mesh(mesh) + , _save(false) + , _modifykernel(mod) +{} Segment::Segment(const MeshObject* mesh, const std::vector& inds, bool mod) - : _mesh(mesh) - , _indices(inds) - , _save(false) - , _modifykernel(mod) + : _mesh(mesh) + , _indices(inds) + , _save(false) + , _modifykernel(mod) { - if (_modifykernel) + if (_modifykernel) { _mesh->updateMesh(inds); + } } void Segment::addIndices(const std::vector& inds) @@ -55,8 +55,9 @@ void Segment::addIndices(const std::vector& inds) _indices.insert(_indices.end(), inds.begin(), inds.end()); std::sort(_indices.begin(), _indices.end()); _indices.erase(std::unique(_indices.begin(), _indices.end()), _indices.end()); - if (_modifykernel) + if (_modifykernel) { _mesh->updateMesh(inds); + } } void Segment::removeIndices(const std::vector& inds) @@ -65,12 +66,16 @@ void Segment::removeIndices(const std::vector& inds) std::vector result; std::set s1(_indices.begin(), _indices.end()); std::set s2(inds.begin(), inds.end()); - std::set_difference(s1.begin(), s1.end(), s2.begin(), s2.end(), - std::back_insert_iterator >(result)); + std::set_difference(s1.begin(), + s1.end(), + s2.begin(), + s2.end(), + std::back_insert_iterator>(result)); _indices = result; - if (_modifykernel) + if (_modifykernel) { _mesh->updateMesh(); + } } const std::vector& Segment::getIndices() const @@ -82,33 +87,38 @@ Segment::Segment(const Segment& s) = default; Segment::Segment(Segment&& s) = default; -Segment& Segment::operator = (const Segment& s) +Segment& Segment::operator=(const Segment& s) { // Do not copy the MeshObject pointer - if (this != &s) + if (this != &s) { this->_indices = s._indices; - if (_modifykernel) + } + if (_modifykernel) { _mesh->updateMesh(); + } return *this; } -Segment& Segment::operator = (Segment&& s) +Segment& Segment::operator=(Segment&& s) { // Do not copy the MeshObject pointer - if (this != &s) + if (this != &s) { this->_indices = s._indices; - if (_modifykernel) + } + if (_modifykernel) { _mesh->updateMesh(); + } return *this; } -bool Segment::operator == (const Segment& s) const +bool Segment::operator==(const Segment& s) const { return this->_indices == s._indices; } // ---------------------------------------------------------------------------- +// clang-format off Segment::const_facet_iterator::const_facet_iterator (const Segment* segm, std::vector::const_iterator it) : _segment(segm), _f_it(segm->_mesh->getKernel()), _it(it) @@ -177,3 +187,4 @@ Segment::const_facet_iterator& Segment::const_facet_iterator::operator--() --(this->_it); return *this; } +// clang-format on diff --git a/src/Mod/Mesh/App/Segment.h b/src/Mod/Mesh/App/Segment.h index 1d1b069482..a8193d9f30 100644 --- a/src/Mod/Mesh/App/Segment.h +++ b/src/Mod/Mesh/App/Segment.h @@ -46,22 +46,43 @@ public: void addIndices(const std::vector& inds); void removeIndices(const std::vector& inds); const std::vector& getIndices() const; - bool isEmpty() const { return _indices.empty(); } + bool isEmpty() const + { + return _indices.empty(); + } Segment(const Segment&); Segment(Segment&&); - Segment& operator = (const Segment&); - Segment& operator = (Segment&&); - bool operator == (const Segment&) const; + Segment& operator=(const Segment&); + Segment& operator=(Segment&&); + bool operator==(const Segment&) const; - void setName(const std::string& n) { _name = n; } - const std::string& getName() const { return _name; } + void setName(const std::string& n) + { + _name = n; + } + const std::string& getName() const + { + return _name; + } - void setColor(const std::string& c) { _color = c; } - const std::string& getColor() const { return _color; } + void setColor(const std::string& c) + { + _color = c; + } + const std::string& getColor() const + { + return _color; + } - void save(bool on) { _save = on; } - bool isSaved() const { return _save; } + void save(bool on) + { + _save = on; + } + bool isSaved() const + { + return _save; + } // friends friend class MeshObject; @@ -91,6 +112,7 @@ public: bool operator!=(const const_facet_iterator& fi) const; const_facet_iterator& operator++(); const_facet_iterator& operator--(); + private: void dereference() const; const Segment* _segment; @@ -100,12 +122,16 @@ public: }; const_facet_iterator facets_begin() const - { return {this, _indices.begin()}; } + { + return {this, _indices.begin()}; + } const_facet_iterator facets_end() const - { return {this, _indices.end()}; } + { + return {this, _indices.end()}; + } }; -} // namespace Mesh +} // namespace Mesh -#endif // MESH_SEGMENT_H +#endif // MESH_SEGMENT_H diff --git a/src/Mod/Mesh/App/Types.h b/src/Mod/Mesh/App/Types.h index a7d3d2b1f9..89d7b8a272 100644 --- a/src/Mod/Mesh/App/Types.h +++ b/src/Mod/Mesh/App/Types.h @@ -33,6 +33,6 @@ using ElementIndex = MeshCore::ElementIndex; using FacetIndex = MeshCore::FacetIndex; using PointIndex = MeshCore::PointIndex; -} // namespace Mesh +} // namespace Mesh -#endif // MESH_TYPES_H +#endif // MESH_TYPES_H