1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

Compare commits

...

4 Commits

Author SHA1 Message Date
oan
d7a6765b43 0025807: Bad performance of meshing
Added test cases
2019-07-10 19:45:21 +03:00
oan
9e4269d8e6 0029506: DRAW command "incmesh" hangs on the attached planar face with specified deflection.
Added test case
2019-07-10 19:00:30 +03:00
oan
5f55b8e615 0026074: BRepMesh_IncrementalMesh meshes a specific shape for a long time
Added test case
2019-07-10 18:59:28 +03:00
oan
057d4b15e3 0028089: Mesh - New algorithm for triangulation of 2d polygons
Added custom meshing core algorithm to generate base mesh using Delabella library:
https://github.com/msokalski/delabella

# Added CSF_MeshAlgo environment variable to select meshing core without necessity of recompilation
2019-07-10 13:04:25 +03:00
18 changed files with 1738 additions and 31 deletions

View File

@@ -20,7 +20,9 @@
#include <BRepMesh_FaceDiscret.hxx>
#include <BRepMesh_ModelPreProcessor.hxx>
#include <BRepMesh_ModelPostProcessor.hxx>
#include <BRepMesh_MeshAlgoFactory.hxx>
#include <BRepMesh_DelabellaMeshAlgoFactory.hxx>
//=======================================================================
// Function: Constructor
@@ -28,11 +30,33 @@
//=======================================================================
BRepMesh_Context::BRepMesh_Context ()
{
enum MeshAlgo
{
MeshAlgo_Default = 0x0,
MeshAlgo_Delabella = 0x1
};
char* anAlgoVar;
anAlgoVar = getenv ("CSF_MeshAlgo");
const Standard_Integer anAlgoId = (anAlgoVar ? atoi (anAlgoVar) : MeshAlgo_Default);
Handle (IMeshTools_MeshAlgoFactory) aAlgoFactory;
switch (anAlgoId)
{
case MeshAlgo_Delabella:
aAlgoFactory = new BRepMesh_DelabellaMeshAlgoFactory;
break;
default:
aAlgoFactory = new BRepMesh_MeshAlgoFactory;
break;
}
SetModelBuilder (new BRepMesh_ModelBuilder);
SetEdgeDiscret (new BRepMesh_EdgeDiscret);
SetModelHealer (new BRepMesh_ModelHealer);
SetPreProcessor (new BRepMesh_ModelPreProcessor);
SetFaceDiscret (new BRepMesh_FaceDiscret(new BRepMesh_MeshAlgoFactory));
SetFaceDiscret (new BRepMesh_FaceDiscret (aAlgoFactory));
SetPostProcessor(new BRepMesh_ModelPostProcessor);
}

View File

@@ -49,12 +49,35 @@ protected:
Standard_EXPORT virtual void generateMesh () Standard_OVERRIDE
{
const Handle (BRepMesh_DataStructureOfDelaun)& aStructure = this->getStructure ();
const Standard_Integer aNodesNb = aStructure->NbNodes ();
buildBaseTriangulation ();
std::pair<Standard_Integer, Standard_Integer> aCellsCount = this->getCellsCount (aStructure->NbNodes ());
BRepMesh_Delaun aMesher (aStructure, aCellsCount.first, aCellsCount.second, Standard_False);
const Standard_Integer aNewNodesNb = aStructure->NbNodes ();
const Standard_Boolean isRemoveAux = aNewNodesNb > aNodesNb;
if (isRemoveAux)
{
IMeshData::VectorOfInteger aAuxVertices (aNewNodesNb - aNodesNb);
for (Standard_Integer aExtNodesIt = aNodesNb + 1; aExtNodesIt <= aNewNodesNb; ++aExtNodesIt)
{
aAuxVertices.Append (aExtNodesIt);
}
// Set aux vertices if there are some to clean up mesh correctly.
aMesher.SetAuxVertices (aAuxVertices);
}
aMesher.ProcessConstraints ();
// Destruction of triangles containing aux vertices added (possibly) during base mesh computation.
if (isRemoveAux)
{
aMesher.RemoveAuxElements ();
}
BRepMesh_MeshTool aCleaner (aStructure);
aCleaner.EraseFreeLinks ();

View File

@@ -0,0 +1,155 @@
// Created on: 2019-07-05
// Copyright (c) 2019 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.
#include <BRepMesh_DelabellaBaseMeshAlgo.hxx>
#include <BRepMesh_MeshTool.hxx>
#include <BRepMesh_Delaun.hxx>
#include "delabella.h"
//=======================================================================
// Function: Constructor
// Purpose :
//=======================================================================
BRepMesh_DelabellaBaseMeshAlgo::BRepMesh_DelabellaBaseMeshAlgo ()
{
}
//=======================================================================
// Function: Destructor
// Purpose :
//=======================================================================
BRepMesh_DelabellaBaseMeshAlgo::~BRepMesh_DelabellaBaseMeshAlgo ()
{
}
//=======================================================================
//function : buildBaseTriangulation
//purpose :
//=======================================================================
void BRepMesh_DelabellaBaseMeshAlgo::buildBaseTriangulation()
{
const Handle(BRepMesh_DataStructureOfDelaun)& aStructure = this->getStructure();
Bnd_B2d aBox;
const Standard_Integer aNodesNb = aStructure->NbNodes ();
std::vector<Standard_Real> aPoints (2 * (aNodesNb + 4));
for (Standard_Integer aNodeIt = 0; aNodeIt < aNodesNb; ++aNodeIt)
{
const BRepMesh_Vertex& aVertex = aStructure->GetNode (aNodeIt + 1);
const size_t aBaseIdx = 2 * static_cast<size_t> (aNodeIt);
aPoints[aBaseIdx + 0] = aVertex.Coord ().X ();
aPoints[aBaseIdx + 1] = aVertex.Coord ().Y ();
aBox.Add (gp_Pnt2d(aVertex.Coord ()));
}
aBox.Enlarge (0.1 * (aBox.CornerMax () - aBox.CornerMin ()).Modulus ());
const gp_XY aMin = aBox.CornerMin ();
const gp_XY aMax = aBox.CornerMax ();
aPoints[2 * aNodesNb + 0] = aMin.X ();
aPoints[2 * aNodesNb + 1] = aMin.Y ();
aStructure->AddNode (BRepMesh_Vertex (
aPoints[2 * aNodesNb + 0],
aPoints[2 * aNodesNb + 1], BRepMesh_Free));
aPoints[2 * aNodesNb + 2] = aMax.X ();
aPoints[2 * aNodesNb + 3] = aMin.Y ();
aStructure->AddNode (BRepMesh_Vertex (
aPoints[2 * aNodesNb + 2],
aPoints[2 * aNodesNb + 3], BRepMesh_Free));
aPoints[2 * aNodesNb + 4] = aMax.X ();
aPoints[2 * aNodesNb + 5] = aMax.Y ();
aStructure->AddNode (BRepMesh_Vertex (
aPoints[2 * aNodesNb + 4],
aPoints[2 * aNodesNb + 5], BRepMesh_Free));
aPoints[2 * aNodesNb + 6] = aMin.X ();
aPoints[2 * aNodesNb + 7] = aMax.Y ();
aStructure->AddNode (BRepMesh_Vertex (
aPoints[2 * aNodesNb + 6],
aPoints[2 * aNodesNb + 7], BRepMesh_Free));
const Standard_Real aDiffX = (aMax.X () - aMin.X ());
const Standard_Real aDiffY = (aMax.Y () - aMin.Y ());
for (size_t i = 0; i < aPoints.size(); i += 2)
{
aPoints[i + 0] = (aPoints[i + 0] - aMin.X ()) / aDiffX - 0.5;
aPoints[i + 1] = (aPoints[i + 1] - aMin.Y ()) / aDiffY - 0.5;
}
IDelaBella* aTriangulator = IDelaBella::Create();
try
{
if (aTriangulator != NULL)
{
const int aVerticesNb = aTriangulator->Triangulate (
static_cast<int>(aPoints.size () / 2),
&aPoints[0], &aPoints[1], 2 * sizeof (Standard_Real));
if (aVerticesNb > 0)
{
const DelaBella_Triangle* aTrianglePtr = aTriangulator->GetFirstDelaunayTriangle();
while (aTrianglePtr != NULL)
{
Standard_Integer aNodes[3] = {
aTrianglePtr->v[0]->i + 1,
aTrianglePtr->v[2]->i + 1,
aTrianglePtr->v[1]->i + 1
};
Standard_Integer aEdges [3];
Standard_Boolean aOrientations[3];
for (Standard_Integer k = 0; k < 3; ++k)
{
const BRepMesh_Edge aLink (aNodes[k], aNodes[(k + 1) % 3], BRepMesh_Free);
const Standard_Integer aLinkInfo = aStructure->AddLink (aLink);
aEdges [k] = Abs (aLinkInfo);
aOrientations[k] = aLinkInfo > 0;
}
const BRepMesh_Triangle aTriangle (aEdges, aOrientations, BRepMesh_Free);
aStructure->AddElement (aTriangle);
aTrianglePtr = aTrianglePtr->next;
}
}
aTriangulator->Destroy ();
}
}
catch (Standard_Failure const& theException)
{
if (aTriangulator != NULL)
{
aTriangulator->Destroy ();
}
throw Standard_Failure (theException);
}
catch (...)
{
if (aTriangulator != NULL)
{
aTriangulator->Destroy ();
}
throw Standard_Failure ("BRepMesh_DelabellaBaseMeshAlgo::buildBaseTriangulation: exception in triangulation algorithm");
}
}

View File

@@ -0,0 +1,46 @@
// Created on: 2019-07-05
// Copyright (c) 2019 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_DelabellaBaseMeshAlgo_HeaderFile
#define _BRepMesh_DelabellaBaseMeshAlgo_HeaderFile
#include <BRepMesh_CustomBaseMeshAlgo.hxx>
#include <NCollection_Shared.hxx>
#include <IMeshTools_Parameters.hxx>
class BRepMesh_DataStructureOfDelaun;
class BRepMesh_Delaun;
//! Class provides base fuctionality to build face triangulation using Delabella project.
//! Performs generation of mesh using raw data from model.
class BRepMesh_DelabellaBaseMeshAlgo : public BRepMesh_CustomBaseMeshAlgo
{
public:
//! Constructor.
Standard_EXPORT BRepMesh_DelabellaBaseMeshAlgo ();
//! Destructor.
Standard_EXPORT virtual ~BRepMesh_DelabellaBaseMeshAlgo ();
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelabellaBaseMeshAlgo, BRepMesh_CustomBaseMeshAlgo)
protected:
//! Builds base triangulation using Delabella project.
Standard_EXPORT virtual void buildBaseTriangulation() Standard_OVERRIDE;
};
#endif

View File

@@ -0,0 +1,143 @@
// Created on: 2019-07-05
// Copyright (c) 2019 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.
#include <BRepMesh_DelabellaMeshAlgoFactory.hxx>
#include <BRepMesh_DefaultRangeSplitter.hxx>
#include <BRepMesh_NURBSRangeSplitter.hxx>
#include <BRepMesh_SphereRangeSplitter.hxx>
#include <BRepMesh_CylinderRangeSplitter.hxx>
#include <BRepMesh_ConeRangeSplitter.hxx>
#include <BRepMesh_TorusRangeSplitter.hxx>
#include <BRepMesh_DelaunayBaseMeshAlgo.hxx>
#include <BRepMesh_DelabellaBaseMeshAlgo.hxx>
#include <BRepMesh_CustomDelaunayBaseMeshAlgo.hxx>
#include <BRepMesh_DelaunayNodeInsertionMeshAlgo.hxx>
#include <BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx>
#include <BRepMesh_BoundaryParamsRangeSplitter.hxx>
namespace
{
struct DefaultBaseMeshAlgo
{
typedef BRepMesh_DelaunayBaseMeshAlgo Type;
};
template<class RangeSplitter>
struct DefaultNodeInsertionMeshAlgo
{
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo> Type;
};
struct BaseMeshAlgo
{
typedef BRepMesh_DelabellaBaseMeshAlgo Type;
};
template<class RangeSplitter>
struct NodeInsertionMeshAlgo
{
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BRepMesh_CustomDelaunayBaseMeshAlgo<BRepMesh_DelabellaBaseMeshAlgo> > Type;
};
template<class RangeSplitter>
struct DeflectionControlMeshAlgo
{
typedef BRepMesh_DelaunayDeflectionControlMeshAlgo<RangeSplitter, BRepMesh_CustomDelaunayBaseMeshAlgo<BRepMesh_DelabellaBaseMeshAlgo> > Type;
};
}
//=======================================================================
// Function: Constructor
// Purpose :
//=======================================================================
BRepMesh_DelabellaMeshAlgoFactory::BRepMesh_DelabellaMeshAlgoFactory ()
{
}
//=======================================================================
// Function: Destructor
// Purpose :
//=======================================================================
BRepMesh_DelabellaMeshAlgoFactory::~BRepMesh_DelabellaMeshAlgoFactory ()
{
}
//=======================================================================
// Function: GetAlgo
// Purpose :
//=======================================================================
Handle(IMeshTools_MeshAlgo) BRepMesh_DelabellaMeshAlgoFactory::GetAlgo(
const GeomAbs_SurfaceType theSurfaceType,
const IMeshTools_Parameters& theParameters) const
{
switch (theSurfaceType)
{
case GeomAbs_Plane:
return theParameters.InternalVerticesMode ?
new NodeInsertionMeshAlgo<BRepMesh_DefaultRangeSplitter>::Type :
new BaseMeshAlgo::Type;
break;
case GeomAbs_Sphere:
{
NodeInsertionMeshAlgo<BRepMesh_SphereRangeSplitter>::Type* aMeshAlgo =
new NodeInsertionMeshAlgo<BRepMesh_SphereRangeSplitter>::Type;
aMeshAlgo->SetPreProcessSurfaceNodes (Standard_True);
return aMeshAlgo;
}
break;
case GeomAbs_Cylinder:
return theParameters.InternalVerticesMode ?
new DefaultNodeInsertionMeshAlgo<BRepMesh_CylinderRangeSplitter>::Type :
new DefaultBaseMeshAlgo::Type;
break;
case GeomAbs_Cone:
{
NodeInsertionMeshAlgo<BRepMesh_ConeRangeSplitter>::Type* aMeshAlgo =
new NodeInsertionMeshAlgo<BRepMesh_ConeRangeSplitter>::Type;
aMeshAlgo->SetPreProcessSurfaceNodes (Standard_True);
return aMeshAlgo;
}
break;
case GeomAbs_Torus:
{
NodeInsertionMeshAlgo<BRepMesh_TorusRangeSplitter>::Type* aMeshAlgo =
new NodeInsertionMeshAlgo<BRepMesh_TorusRangeSplitter>::Type;
aMeshAlgo->SetPreProcessSurfaceNodes (Standard_True);
return aMeshAlgo;
}
break;
case GeomAbs_SurfaceOfRevolution:
{
DeflectionControlMeshAlgo<BRepMesh_BoundaryParamsRangeSplitter>::Type* aMeshAlgo =
new DeflectionControlMeshAlgo<BRepMesh_BoundaryParamsRangeSplitter>::Type;
aMeshAlgo->SetPreProcessSurfaceNodes (Standard_True);
return aMeshAlgo;
}
break;
default:
{
DeflectionControlMeshAlgo<BRepMesh_NURBSRangeSplitter>::Type* aMeshAlgo =
new DeflectionControlMeshAlgo<BRepMesh_NURBSRangeSplitter>::Type;
aMeshAlgo->SetPreProcessSurfaceNodes (Standard_True);
return aMeshAlgo;
}
}
}

View File

@@ -0,0 +1,44 @@
// Created on: 2019-07-05
// Copyright (c) 2019 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_DelabellaMeshAlgoFactory_HeaderFile
#define _BRepMesh_DelabellaMeshAlgoFactory_HeaderFile
#include <Standard_Transient.hxx>
#include <Standard_Type.hxx>
#include <GeomAbs_SurfaceType.hxx>
#include <IMeshTools_MeshAlgoFactory.hxx>
//! Implementation of IMeshTools_MeshAlgoFactory providing Delabella-based
//! algorithms of different compexity depending on type of target surface.
class BRepMesh_DelabellaMeshAlgoFactory : public IMeshTools_MeshAlgoFactory
{
public:
//! Constructor.
Standard_EXPORT BRepMesh_DelabellaMeshAlgoFactory ();
//! Destructor.
Standard_EXPORT virtual ~BRepMesh_DelabellaMeshAlgoFactory ();
//! Creates instance of meshing algorithm for the given type of surface.
Standard_EXPORT virtual Handle(IMeshTools_MeshAlgo) GetAlgo(
const GeomAbs_SurfaceType theSurfaceType,
const IMeshTools_Parameters& theParameters) const Standard_OVERRIDE;
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelabellaMeshAlgoFactory, IMeshTools_MeshAlgoFactory)
};
#endif

View File

@@ -89,7 +89,8 @@ BRepMesh_Delaun::BRepMesh_Delaun (
const Standard_Boolean isFillCircles)
: myMeshData ( theOldMesh ),
myCircles (new NCollection_IncAllocator(
IMeshData::MEMORY_BLOCK_SIZE_HUGE))
IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
mySupVert (3)
{
if (isFillCircles)
{
@@ -103,7 +104,8 @@ BRepMesh_Delaun::BRepMesh_Delaun (
//=======================================================================
BRepMesh_Delaun::BRepMesh_Delaun(IMeshData::Array1OfVertexOfDelaun& theVertices)
: myCircles (theVertices.Length(), new NCollection_IncAllocator(
IMeshData::MEMORY_BLOCK_SIZE_HUGE))
IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
mySupVert (3)
{
if ( theVertices.Length() > 2 )
{
@@ -123,7 +125,8 @@ BRepMesh_Delaun::BRepMesh_Delaun(
IMeshData::Array1OfVertexOfDelaun& theVertices)
: myMeshData( theOldMesh ),
myCircles ( theVertices.Length(), new NCollection_IncAllocator(
IMeshData::MEMORY_BLOCK_SIZE_HUGE))
IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
mySupVert (3)
{
if ( theVertices.Length() > 2 )
{
@@ -140,7 +143,8 @@ BRepMesh_Delaun::BRepMesh_Delaun(
IMeshData::VectorOfInteger& theVertexIndices)
: myMeshData( theOldMesh ),
myCircles ( theVertexIndices.Length(), new NCollection_IncAllocator(
IMeshData::MEMORY_BLOCK_SIZE_HUGE))
IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
mySupVert (3)
{
perform(theVertexIndices);
}
@@ -155,7 +159,8 @@ BRepMesh_Delaun::BRepMesh_Delaun (const Handle (BRepMesh_DataStructureOfDelaun)&
const Standard_Integer theCellsCountV)
: myMeshData (theOldMesh),
myCircles (theVertexIndices.Length (), new NCollection_IncAllocator(
IMeshData::MEMORY_BLOCK_SIZE_HUGE))
IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
mySupVert (3)
{
perform (theVertexIndices, theCellsCountU, theCellsCountV);
}
@@ -284,14 +289,14 @@ void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox)
Standard_Real aDeltaMax = Max( aDeltaX, aDeltaY );
Standard_Real aDelta = aDeltaX + aDeltaY;
mySupVert[0] = myMeshData->AddNode(
BRepMesh_Vertex( ( aMinX + aMaxX ) / 2, aMaxY + aDeltaMax, BRepMesh_Free ) );
mySupVert.Append (myMeshData->AddNode(
BRepMesh_Vertex( ( aMinX + aMaxX ) / 2, aMaxY + aDeltaMax, BRepMesh_Free ) ) );
mySupVert[1] = myMeshData->AddNode(
BRepMesh_Vertex( aMinX - aDelta, aMinY - aDeltaMin, BRepMesh_Free ) );
mySupVert.Append (myMeshData->AddNode(
BRepMesh_Vertex( aMinX - aDelta, aMinY - aDeltaMin, BRepMesh_Free ) ) );
mySupVert[2] = myMeshData->AddNode(
BRepMesh_Vertex( aMaxX + aDelta, aMinY - aDeltaMin, BRepMesh_Free ) );
mySupVert.Append (myMeshData->AddNode(
BRepMesh_Vertex( aMaxX + aDelta, aMinY - aDeltaMin, BRepMesh_Free ) ) );
Standard_Integer e[3];
Standard_Boolean o[3];
@@ -300,7 +305,7 @@ void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox)
Standard_Integer aFirstNode = aNodeId;
Standard_Integer aLastNode = (aNodeId + 1) % 3;
Standard_Integer aLinkIndex = myMeshData->AddLink( BRepMesh_Edge(
mySupVert[aFirstNode], mySupVert[aLastNode], BRepMesh_Free ) );
mySupVert (aFirstNode), mySupVert (aLastNode), BRepMesh_Free ) );
e[aNodeId] = Abs(aLinkIndex);
o[aNodeId] = (aLinkIndex > 0);
@@ -367,28 +372,41 @@ void BRepMesh_Delaun::compute(IMeshData::VectorOfInteger& theVertexIndexes)
createTrianglesOnNewVertices( theVertexIndexes );
}
RemoveAuxElements ();
}
//=======================================================================
//function : RemoveAuxElements
//purpose :
//=======================================================================
void BRepMesh_Delaun::RemoveAuxElements ()
{
Handle (NCollection_IncAllocator) aAllocator = new NCollection_IncAllocator (
IMeshData::MEMORY_BLOCK_SIZE_HUGE);
IMeshData::MapOfIntegerInteger aLoopEdges (10, aAllocator);
// Destruction of triangles containing a top of the super triangle
BRepMesh_SelectorOfDataStructureOfDelaun aSelector( myMeshData );
for (Standard_Integer aSupVertId = 0; aSupVertId < 3; ++aSupVertId)
aSelector.NeighboursOfNode( mySupVert[aSupVertId] );
aLoopEdges.Clear();
IMeshData::IteratorOfMapOfInteger aFreeTriangles( aSelector.Elements() );
for ( ; aFreeTriangles.More(); aFreeTriangles.Next() )
deleteTriangle( aFreeTriangles.Key(), aLoopEdges );
BRepMesh_SelectorOfDataStructureOfDelaun aSelector (myMeshData);
for (Standard_Integer aSupVertId = 0; aSupVertId < mySupVert.Size(); ++aSupVertId)
aSelector.NeighboursOfNode (mySupVert (aSupVertId));
IMeshData::IteratorOfMapOfInteger aFreeTriangles (aSelector.Elements ());
for (; aFreeTriangles.More (); aFreeTriangles.Next ())
deleteTriangle (aFreeTriangles.Key (), aLoopEdges);
// All edges that remain free are removed from aLoopEdges;
// only the boundary edges of the triangulation remain there
IMeshData::MapOfIntegerInteger::Iterator aFreeEdges( aLoopEdges );
for ( ; aFreeEdges.More(); aFreeEdges.Next() )
IMeshData::MapOfIntegerInteger::Iterator aFreeEdges (aLoopEdges);
for (; aFreeEdges.More (); aFreeEdges.Next ())
{
if ( myMeshData->ElementsConnectedTo( aFreeEdges.Key() ).IsEmpty() )
myMeshData->RemoveLink( aFreeEdges.Key() );
if (myMeshData->ElementsConnectedTo (aFreeEdges.Key ()).IsEmpty ())
myMeshData->RemoveLink (aFreeEdges.Key ());
}
// The tops of the super triangle are destroyed
for (Standard_Integer aSupVertId = 0; aSupVertId < 3; ++aSupVertId)
myMeshData->RemoveNode( mySupVert[aSupVertId] );
for (Standard_Integer aSupVertId = 0; aSupVertId < mySupVert.Size (); ++aSupVertId)
myMeshData->RemoveNode (mySupVert (aSupVertId));
}
//=======================================================================
@@ -771,9 +789,7 @@ void BRepMesh_Delaun::cleanupMesh()
myMeshData->ElementNodes (aCurTriangle, v);
for (int aNodeIdx = 0; aNodeIdx < 3 && isCanNotBeRemoved; ++aNodeIdx)
{
if (v[aNodeIdx] == mySupVert[0] ||
v[aNodeIdx] == mySupVert[1] ||
v[aNodeIdx] == mySupVert[2])
if (isSupVertex (v[aNodeIdx]))
{
isCanNotBeRemoved = Standard_False;
}

View File

@@ -147,6 +147,17 @@ public:
const Standard_Real theSqTolerance,
Standard_Integer& theEdgeOn) const;
//! Explicitly sets ids of auxiliary vertices used to build mesh and used by 3rd-party algorithms.
inline void SetAuxVertices (const IMeshData::VectorOfInteger& theSupVert)
{
mySupVert = theSupVert;
}
//! Destruction of auxiliary triangles containing the given vertices.
//! Removes auxiliary vertices also.
//! @param theAuxVertices auxiliary vertices to be cleaned up.
Standard_EXPORT void RemoveAuxElements ();
private:
enum ReplaceFlag
@@ -354,11 +365,25 @@ private:
//! Performs insertion of internal edges into mesh.
void insertInternalEdges();
//! Checks whether the given vertex id relates to super contour.
inline Standard_Boolean isSupVertex (const Standard_Integer theVertexIdx)
{
for (IMeshData::VectorOfInteger::Iterator aIt (mySupVert); aIt.More (); aIt.Next ())
{
if (theVertexIdx == aIt.Value ())
{
return Standard_True;
}
}
return Standard_False;
}
private:
Handle(BRepMesh_DataStructureOfDelaun) myMeshData;
BRepMesh_CircleTool myCircles;
Standard_Integer mySupVert[3];
IMeshData::VectorOfInteger mySupVert;
BRepMesh_Triangle mySupTrian;
};

View File

@@ -0,0 +1,22 @@
MIT License
DELABELLA - Delaunay triangulation library
Copyright (C) 2018 GUMIX - Marcin Sokalski
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -86,3 +86,9 @@ BRepMesh_VertexTool.cxx
BRepMesh_VertexTool.hxx
BRepMesh_CustomBaseMeshAlgo.hxx
BRepMesh_CustomDelaunayBaseMeshAlgo.hxx
delabella.h
delabella.cpp
BRepMesh_DelabellaBaseMeshAlgo.hxx
BRepMesh_DelabellaBaseMeshAlgo.cxx
BRepMesh_DelabellaMeshAlgoFactory.hxx
BRepMesh_DelabellaMeshAlgoFactory.cxx

1021
src/BRepMesh/delabella.cpp Normal file

File diff suppressed because it is too large Load Diff

68
src/BRepMesh/delabella.h Normal file
View File

@@ -0,0 +1,68 @@
/*
DELABELLA - Delaunay triangulation library
Copyright (C) 2018 GUMIX - Marcin Sokalski
*/
#ifndef DELABELLA_H
#define DELABELLA_H
// returns: positive value: number of triangle indices, negative: number of line segment indices (degenerated input)
// triangle indices in abc array are always returned in clockwise order
// DEPRECIATED. move to new API either extern "C" or IDelaBella (C++)
int DelaBella(int points, const double* xy/*[points][2]*/, int* abc/*[2*points-5][3]*/, int (*errlog)(const char* fmt,...) = printf);
struct DelaBella_Vertex
{
int i; // index of original point
double x, y; // coordinates (input copy)
DelaBella_Vertex* next; // next silhouette vertex
};
struct DelaBella_Triangle
{
DelaBella_Vertex* v[3]; // 3 vertices spanning this triangle
DelaBella_Triangle* f[3]; // 3 adjacent faces, f[i] is at the edge opposite to vertex v[i]
DelaBella_Triangle* next; // next triangle (of delaunay set or hull set)
};
#ifdef __cplusplus
struct IDelaBella
{
static IDelaBella* Create();
virtual void Destroy() = 0;
virtual void SetErrLog(int(*proc)(void* stream, const char* fmt, ...), void* stream) = 0;
// return 0: no output
// negative: all points are colinear, output hull vertices form colinear segment list, no triangles on output
// positive: output hull vertices form counter-clockwise ordered segment contour, delaunay and hull triangles are available
// if 'y' pointer is null, y coords are treated to be located immediately after every x
// if advance_bytes is less than 2*sizeof coordinate type, it is treated as 2*sizeof coordinate type
virtual int Triangulate(int points, const float* x, const float* y = 0, int advance_bytes = 0) = 0;
virtual int Triangulate(int points, const double* x, const double* y = 0, int advance_bytes = 0) = 0;
// num of points passed to last call to Triangulate()
virtual int GetNumInputPoints() const = 0;
// num of verts returned from last call to Triangulate()
virtual int GetNumOutputVerts() const = 0;
virtual const DelaBella_Triangle* GetFirstDelaunayTriangle() const = 0; // valid only if Triangulate() > 0
virtual const DelaBella_Triangle* GetFirstHullTriangle() const = 0; // valid only if Triangulate() > 0
virtual const DelaBella_Vertex* GetFirstHullVertex() const = 0; // if Triangulate() < 0 it is list, otherwise closed contour!
};
#else
void* DelaBella_Create();
void DelaBella_Destroy(void* db);
void DelaBella_SetErrLog(void* db, int(*proc)(void* stream, const char* fmt, ...), void* stream);
int DelaBella_TriangulateFloat(void* db, int points, float* x, float* y = 0, int advance_bytes = 0);
int DelaBella_TriangulateDouble(void* db, int points, double* x, double* y = 0, int advance_bytes = 0);
int DelaBella_GetNumInputPoints(void* db);
int DelaBella_GetNumOutputVerts(void* db);
const DelaBella_Triangle* GetFirstDelaunayTriangle(void* db);
const DelaBella_Triangle* GetFirstHullTriangle(void* db);
const DelaBella_Vertex* GetFirstHullVertex(void* db);
#endif
#endif

View File

@@ -0,0 +1,19 @@
puts "========="
puts "0025807: Bad performance of meshing"
puts "========="
puts ""
set ::env(CSF_MeshAlgo) 1
restore [locate_data_file shape_506819_1.brep] result
tclean result
incmesh result 0.001
checktrinfo result -tri 25314 -nod 59186 -defl 0.0010000000000000007
vinit
vsetdispmode 1
vdefaults -autoTriang 0
vdisplay result
vfit
checkview -screenshot -3d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,19 @@
puts "========="
puts "0025807: Bad performance of meshing"
puts "========="
puts ""
set ::env(CSF_MeshAlgo) 1
restore [locate_data_file shape_778972_1.brep] result
tclean result
incmesh result 0.001
checktrinfo result -tri 19974 -nod 46036 -defl 0.0010000000000000007
vinit
vsetdispmode 1
vdefaults -autoTriang 0
vdisplay result
vfit
checkview -screenshot -3d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,19 @@
puts "========="
puts "0025807: Bad performance of meshing"
puts "========="
puts ""
set ::env(CSF_MeshAlgo) 1
restore [locate_data_file shape_894944_1.brep] result
tclean result
incmesh result 0.001
checktrinfo result -tri 26774 -nod 62436 -defl 0.0010000000000000007
vinit
vsetdispmode 1
vdefaults -autoTriang 0
vdisplay result
vfit
checkview -screenshot -3d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,19 @@
puts "========="
puts "0025807: Bad performance of meshing"
puts "========="
puts ""
set ::env(CSF_MeshAlgo) 1
restore [locate_data_file shape_1174827_1.brep] result
tclean result
incmesh result 0.001
checktrinfo result -tri 25314 -nod 59186 -defl 0.0010000000000000007
vinit
vsetdispmode 1
vdefaults -autoTriang 0
vdisplay result
vfit
checkview -screenshot -3d -path ${imagedir}/${test_image}.png

19
tests/bugs/mesh/bug26074 Normal file
View File

@@ -0,0 +1,19 @@
puts "========="
puts "0026074: BRepMesh_IncrementalMesh meshes a specific shape for a long time"
puts "========="
puts ""
set ::env(CSF_MeshAlgo) 1
restore [locate_data_file bug26074.brep] result
tclean result
incmesh result 0.01116 -a 15 -parallel
checktrinfo result -tri
vinit
vsetdispmode 1
vdefaults -autoTriang 0
vdisplay result
vfit
checkview -screenshot -3d -path ${imagedir}/${test_image}.png

19
tests/bugs/mesh/bug29506 Normal file
View File

@@ -0,0 +1,19 @@
puts "========="
puts "0029506: DRAW command 'incmesh' hangs on the attached planar face with specified deflection."
puts "========="
puts ""
set ::env(CSF_MeshAlgo) 1
restore [locate_data_file bug29506.brep] result
tclean result
incmesh result 1e-6
checktrinfo result -tri 44437 -nod 44437 -defl 9.9999999999999995e-07
vinit
vsetdispmode 1
vdefaults -autoTriang 0
vdisplay result
vfit
checkview -screenshot -3d -path ${imagedir}/${test_image}.png