1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-21 10:13:43 +03:00
occt/src/BRepMesh/BRepMesh_MeshTool.hxx
oan 7bd071edb1 0026106: BRepMesh - revision of data model
Removed tight connections between data structures, auxiliary tools and algorithms in order to create extensible solution, easy for maintenance and improvements;
Code is separated on several functional units responsible for specific operation for the sake of simplification of debugging and readability;
Introduced new data structures enabling possibility to manipulate discrete model of particular entity (edge, wire, face) in order to perform computations locally instead of processing an entire model.

The workflow of updated component can be divided on six parts:
* Creation of model data structure: source TopoDS_Shape passed to algorithm is analyzed and exploded on faces and edges. For each topological entity corresponding reflection is created in data model. Note that underlying algorithms use data model as input and access it via common interface which allows user to create custom data model with necessary dependencies between particular entities;
* Discretize edges 3D & 2D curves: 3D curve as well as associated set of 2D curves of each model edge is discretized in order to create coherent skeleton used as a base in faces meshing process. In case if some edge of source shape already contains polygonal data which suites specified parameters, it is extracted from shape and stored to the model as is. Each edge is processed separately, adjacency is not taken into account;
* Heal discrete model: source TopoDS_Shape can contain problems, such as open-wire or self-intersections, introduced during design, exchange or modification of model. In addition, some problems like self-intersections can be introduced by roughly discretized edges. This stage is responsible for analysis of discrete model in order to detect and repair faced problems or refuse model’s part for further processing in case if problem cannot be solved;
* Preprocess discrete model: defines actions specific for implemented approach to be performed before meshing of faces. By default, iterates over model faces and checks consistency of existing triangulations. Cleans topological faces and its adjacent edges from polygonal data in case of inconsistency or marks face of discrete model as not required for computation;
* Discretize faces: represents core part performing mesh generation for particular face based on 2D discrete data related to processing face. Caches polygonal data associated with face’s edges in data model for further processing and stores generated mesh to TopoDS_Face;
* Postprocess discrete model: defines actions specific for implemented approach to be performed after meshing of faces. By default, stores polygonal data obtained on previous stage to TopoDS_Edge objects of source model.

Component is now spread over IMeshData, IMeshTools, BRepMeshData and BRepMesh units.

<!break>

1. Extend "tricheck" DRAW-command in order to find degenerated triangles.

2. Class BRepMesh_FastDiscret::Parameters has been declared as deprecated.

3. NURBS range splitter: do not split intervals without necessity. Intervals are split only in case if it is impossible to compute normals directly on intervals.

4. Default value of IMeshTools_Parameters::MinSize has been changed. New value is equal to 0.1*Deflection.

5. Correction of test scripts:

1) perf mesh bug27119: requested deflection is increased from 1e-6 to 1e-5 to keep reasonable performance (but still reproducing original issue)
2) bugs mesh bug26692_1, 2: make snapshot of triangulation instead of wireframe (irrelevant)

Correction in upgrade guide.
2018-11-02 17:06:40 +03:00

236 lines
8.1 KiB
C++

// Created on: 2016-08-22
// Copyright (c) 2016 OPEN CASCADE SAS
// Created by: Oleg AGASHIN
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_MeshTool_HeaderFile
#define _BRepMesh_MeshTool_HeaderFile
#include <Standard_Transient.hxx>
#include <Standard_DefineHandle.hxx>
#include <BRepMesh_DataStructureOfDelaun.hxx>
#include <BRepMesh_CircleTool.hxx>
#include <gp_Lin2d.hxx>
#include <IMeshData_Types.hxx>
#include <BRepMesh_Edge.hxx>
#include <stack>
//! Auxiliary tool providing API for manipulation with BRepMesh_DataStructureOfDelaun.
class BRepMesh_MeshTool : public Standard_Transient
{
public:
//! Helper functor intended to separate points to left and right from the constraint.
class NodeClassifier
{
public:
NodeClassifier(
const BRepMesh_Edge& theConstraint,
const Handle(BRepMesh_DataStructureOfDelaun)& theStructure)
: myStructure(theStructure)
{
const BRepMesh_Vertex& aVertex1 = myStructure->GetNode(theConstraint.FirstNode());
const BRepMesh_Vertex& aVertex2 = myStructure->GetNode(theConstraint.LastNode());
myConstraint.SetLocation(aVertex1.Coord());
myConstraint.SetDirection(gp_Vec2d(aVertex1.Coord(), aVertex2.Coord()));
mySign = myConstraint.Direction().X() > 0;
}
inline Standard_Boolean IsAbove(const Standard_Integer theNodeIndex) const
{
const BRepMesh_Vertex& aVertex = myStructure->GetNode(theNodeIndex);
const gp_Vec2d aNodeVec(myConstraint.Location(), aVertex.Coord());
if (aNodeVec.SquareMagnitude() > gp::Resolution())
{
const Standard_Real aCross = aNodeVec.Crossed(myConstraint.Direction());
if (Abs(aCross) > gp::Resolution())
{
return mySign ?
aCross < 0. :
aCross > 0.;
}
}
return Standard_False;
}
private:
NodeClassifier (const NodeClassifier& theOther);
void operator=(const NodeClassifier& theOther);
private:
const Handle(BRepMesh_DataStructureOfDelaun)& myStructure;
gp_Lin2d myConstraint;
Standard_Boolean mySign;
};
//! Constructor.
//! Initializes tool by the given data structure.
Standard_EXPORT BRepMesh_MeshTool(const Handle(BRepMesh_DataStructureOfDelaun)& theStructure);
//! Destructor.
Standard_EXPORT virtual ~BRepMesh_MeshTool();
//! Returns data structure manipulated by this tool.
inline const Handle(BRepMesh_DataStructureOfDelaun)& GetStructure() const
{
return myStructure;
}
//! Dumps triangles to specified file.
void DumpTriangles(const Standard_CString theFileName, IMeshData::MapOfInteger* theTriangles);
//! Adds new triangle with specified nodes to mesh.
//! Legalizes triangle in case if it violates circle criteria.
inline void AddAndLegalizeTriangle(
const Standard_Integer thePoint1,
const Standard_Integer thePoint2,
const Standard_Integer thePoint3)
{
Standard_Integer aEdges[3];
AddTriangle(thePoint1, thePoint2, thePoint3, aEdges);
Legalize(aEdges[0]);
Legalize(aEdges[1]);
Legalize(aEdges[2]);
}
//! Adds new triangle with specified nodes to mesh.
inline void AddTriangle(
const Standard_Integer thePoint1,
const Standard_Integer thePoint2,
const Standard_Integer thePoint3,
Standard_Integer (&theEdges)[3])
{
Standard_Boolean aOri[3];
AddLink(thePoint1, thePoint2, theEdges[0], aOri[0]);
AddLink(thePoint2, thePoint3, theEdges[1], aOri[1]);
AddLink(thePoint3, thePoint1, theEdges[2], aOri[2]);
myStructure->AddElement(BRepMesh_Triangle(theEdges, aOri, BRepMesh_Free));
}
//! Adds new link to mesh.
//! Updates link index and link orientaion parameters.
inline void AddLink(const Standard_Integer theFirstNode,
const Standard_Integer theLastNode,
Standard_Integer& theLinkIndex,
Standard_Boolean& theLinkOri)
{
const Standard_Integer aLinkIt = myStructure->AddLink(
BRepMesh_Edge(theFirstNode, theLastNode, BRepMesh_Free));
theLinkIndex = Abs(aLinkIt);
theLinkOri = (aLinkIt > 0);
}
//! Performs legalization of triangles connected to the specified link.
Standard_EXPORT void Legalize(const Standard_Integer theLinkIndex);
//! Erases all elements connected to the specified artificial node.
//! In addition, erases the artificial node itself.
Standard_EXPORT void EraseItemsConnectedTo(const Standard_Integer theNodeIndex);
//! Cleans frontier links from triangles to the right.
Standard_EXPORT void CleanFrontierLinks();
//! Erases the given set of triangles.
//! Fills map of loop edges forming the countour surrounding the erased triangles.
void EraseTriangles(const IMeshData::MapOfInteger& theTriangles,
IMeshData::MapOfIntegerInteger& theLoopEdges);
//! Erases triangle with the given index and adds the free edges into the map.
//! When an edge is suppressed more than one time it is destroyed.
Standard_EXPORT void EraseTriangle(const Standard_Integer theTriangleIndex,
IMeshData::MapOfIntegerInteger& theLoopEdges);
//! Erases all links that have no elements connected to them.
Standard_EXPORT void EraseFreeLinks();
//! Erases links from the specified map that have no elements connected to them.
Standard_EXPORT void EraseFreeLinks(const IMeshData::MapOfIntegerInteger& theLinks);
//! Gives the list of edges with type defined by input parameter.
Standard_EXPORT Handle(IMeshData::MapOfInteger) GetEdgesByType(const BRepMesh_DegreeOfFreedom theEdgeType) const;
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_MeshTool, Standard_Transient)
private:
//! Returns True if the given point lies within circumcircle of the given triangle.
inline Standard_Boolean checkCircle(
const Standard_Integer(&aNodes)[3],
const Standard_Integer thePoint)
{
const BRepMesh_Vertex& aVertex0 = myStructure->GetNode(aNodes[0]);
const BRepMesh_Vertex& aVertex1 = myStructure->GetNode(aNodes[1]);
const BRepMesh_Vertex& aVertex2 = myStructure->GetNode(aNodes[2]);
gp_XY aLocation;
Standard_Real aRadius;
const Standard_Boolean isOk = BRepMesh_CircleTool::MakeCircle(
aVertex0.Coord(), aVertex1.Coord(), aVertex2.Coord(),
aLocation, aRadius);
if (isOk)
{
const BRepMesh_Vertex& aVertex = myStructure->GetNode(thePoint);
const Standard_Real aDist = (aVertex.Coord() - aLocation).SquareModulus() - (aRadius * aRadius);
return (aDist < Precision::SquareConfusion());
}
return Standard_False;
}
//! Adds new triangle with the given nodes and updates
//! links stack by ones are not in used map.
inline void addTriangleAndUpdateStack(
const Standard_Integer theNode0,
const Standard_Integer theNode1,
const Standard_Integer theNode2,
const IMeshData::MapOfInteger& theUsedLinks,
std::stack<Standard_Integer>& theStack)
{
Standard_Integer aEdges[3];
AddTriangle(theNode0, theNode1, theNode2, aEdges);
for (Standard_Integer i = 0; i < 3; ++i)
{
if (!theUsedLinks.Contains(aEdges[i]))
{
theStack.push(aEdges[i]);
}
}
}
//! Iteratively erases triangles and their neighbours consisting
//! of free links using the given link as starting front.
//! Only triangles around the constraint's saddle nodes will be removed.
void collectTrianglesOnFreeLinksAroundNodesOf(
const BRepMesh_Edge& theConstraint,
const Standard_Integer theStartLink,
IMeshData::MapOfInteger& theTriangles);
private:
Handle(BRepMesh_DataStructureOfDelaun) myStructure;
};
#endif