1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00

0028089: Mesh - New algorithm for triangulation of 2d polygons

Added custom meshing core algorithm to generate base mesh using Delabella library,
which can be enabled via IMeshTools_Parameters::MeshAlgo option or CSF_MeshAlgo environment variable.

Do not fill cirles filter upon explicit initialization.
Call base postProcessMesh functionality after initialization of circles in BRepMesh_CustomDelaunayBaseMeshAlgo.

Added Vsprintf() wrapper for vsprintf() preserving C locale.
This commit is contained in:
oan 2019-07-10 13:04:25 +03:00 committed by bugmaster
parent 689dc3b1c9
commit f2006a6f19
30 changed files with 1923 additions and 68 deletions

View File

@ -156,6 +156,10 @@ RapidJSON is optionally used by OCCT for reading glTF files (https://rapidjson.o
**DejaVu** fonts are a font family based on the Vera Fonts under a permissive license (MIT-like, https://dejavu-fonts.github.io/License.html).
DejaVu Sans (basic Latin sub-set) is used by OCCT as fallback font when no system font is available.
**Delabella** is an open-source, cross-platform implementation of the Newton Apple Wrapper algorithm producing 2D Delaunay triangulation.
Delabella is used by BRepMesh as one of alternative 2D triangulation algorithms.
Delabella is licensed under the MIT license (https://github.com/msokalski/delabella).
Adobe Systems, Inc. provides **Adobe Reader**, which can be used to view files in Portable Document Format (PDF).
@section OCCT_OVW_SECTION_3 Documentation

View File

@ -3251,6 +3251,40 @@ In general, face meshing algorithms have the following structure:
* Classes *BRepMesh_DelaunayNodeInsertionMeshAlgo* and *BRepMesh_SweepLineNodeInsertionMeshAlgo* implement algorithm-specific functionality related to addition of internal nodes supplementing functionality provided by *BRepMesh_NodeInsertionMeshAlgo*;
* *BRepMesh_DelaunayDeflectionControlMeshAlgo* extends functionality of *BRepMesh_DelaunayNodeInsertionMeshAlgo* by additional procedure controlling deflection of generated triangles.
BRepMesh provides user a way to switch default triangulation algorithm to a custom one, either implemented by user or available worldwide.
There are three base classes that can be currently used to integrate 3rd-party algorithms:
* *BRepMesh_ConstrainedBaseMeshAlgo* base class for tools providing generation of triangulations with constraints requiring no common processing by BRepMesh;
* *BRepMesh_CustomBaseMeshAlgo* provides the entry point for generic algorithms without support of constraints and supposed for generation of base mesh only.
Constraint edges are processed using standard functionality provided by the component itself upon background mesh produced by 3rd-party solver;
* *BRepMesh_CustomDelaunayBaseMeshAlgo* contains initialization part for tools used by BRepMesh for checks or optimizations using results of 3rd-party algorithm.
Meshing algorithms could be provided by implemeting IMeshTools_MeshAlgoFactory with related interfaces and passing it to BRepMesh_Context::SetFaceDiscret().
OCCT comes with two base 2D meshing algorithms: BRepMesh_MeshAlgoFactory (used by default) and BRepMesh_DelabellaMeshAlgoFactory.
The following example demonstrates how it could be done from Draw environment:
~~~~~
psphere s 10
### Default Algo ###
incmesh s 0.0001 -algo default
### Delabella Algo ###
incmesh s 0.0001 -algo delabella
~~~~~
The code snippet below shows passing a custom mesh factory to BRepMesh_IncrementalMesh:
~~~~~
IMeshTools_Parameters aMeshParams;
Handle(IMeshTools_Context) aContext = new BRepMesh_Context();
aContext->SetFaceDiscret (new BRepMesh_FaceDiscret (new BRepMesh_DelabellaMeshAlgoFactory()));
BRepMesh_IncrementalMesh aMesher;
aMesher.SetShape (aShape);
aMesher.ChangeParameters() = aMeshParams;
aMesher.Perform (aContext);
~~~~~
#### Range splitter
Range splitter tools provide functionality to generate internal surface nodes defined within the range computed using discrete model data. The base functionality is provided by *BRepMesh_DefaultRangeSplitter* which can be used without modifications in case of planar surface. The default splitter does not generate any internal node.

View File

@ -25,7 +25,7 @@
class BRepMesh_DataStructureOfDelaun;
class BRepMesh_Delaun;
//! Class provides base fuctionality for algorithms building face triangulation.
//! Class provides base functionality for algorithms building face triangulation.
//! Performs initialization of BRepMesh_DataStructureOfDelaun and nodes map structures.
class BRepMesh_BaseMeshAlgo : public IMeshTools_MeshAlgo
{
@ -108,7 +108,7 @@ protected:
private:
//! If the given edge has another pcurve for current face coinsiding with specified one,
//! If the given edge has another pcurve for current face coinciding with specified one,
//! returns TopAbs_INTERNAL flag. Elsewhere returns orientation of specified pcurve.
TopAbs_Orientation fixSeamEdgeOrientation(
const IMeshData::IEdgeHandle& theDEdge,

View File

@ -23,7 +23,7 @@
class BRepMesh_DataStructureOfDelaun;
class BRepMesh_Delaun;
//! Class provides base fuctionality to build face triangulation using Dealunay approach.
//! Class provides base functionality to build face triangulation using Dealunay approach.
//! Performs generation of mesh using raw data from model.
class BRepMesh_ConstrainedBaseMeshAlgo : public BRepMesh_BaseMeshAlgo
{
@ -49,7 +49,7 @@ protected:
return std::pair<Standard_Integer, Standard_Integer> (-1, -1);
}
//! Perfroms processing of generated mesh.
//! Performs processing of generated mesh.
//! By default does nothing.
//! Expected to be called from method generateMesh() in successor classes.
virtual void postProcessMesh (BRepMesh_Delaun& /*theMesher*/,

View File

@ -20,19 +20,59 @@
#include <BRepMesh_FaceDiscret.hxx>
#include <BRepMesh_ModelPreProcessor.hxx>
#include <BRepMesh_ModelPostProcessor.hxx>
#include <BRepMesh_MeshAlgoFactory.hxx>
#include <BRepMesh_DelabellaMeshAlgoFactory.hxx>
#include <Message.hxx>
#include <OSD_Environment.hxx>
//=======================================================================
// Function: Constructor
// Purpose :
//=======================================================================
BRepMesh_Context::BRepMesh_Context ()
BRepMesh_Context::BRepMesh_Context (IMeshTools_MeshAlgoType theMeshType)
{
if (theMeshType == IMeshTools_MeshAlgoType_DEFAULT)
{
TCollection_AsciiString aValue = OSD_Environment ("CSF_MeshAlgo").Value();
aValue.LowerCase();
if (aValue == "watson"
|| aValue == "0")
{
theMeshType = IMeshTools_MeshAlgoType_Watson;
}
else if (aValue == "delabella"
|| aValue == "1")
{
theMeshType = IMeshTools_MeshAlgoType_Delabella;
}
else
{
if (!aValue.IsEmpty())
{
Message::SendWarning (TCollection_AsciiString("BRepMesh_Context, ignore unknown algorithm '") + aValue + "' specified in CSF_MeshAlgo variable");
}
theMeshType = IMeshTools_MeshAlgoType_Watson;
}
}
Handle (IMeshTools_MeshAlgoFactory) aAlgoFactory;
switch (theMeshType)
{
case IMeshTools_MeshAlgoType_DEFAULT:
case IMeshTools_MeshAlgoType_Watson:
aAlgoFactory = new BRepMesh_MeshAlgoFactory();
break;
case IMeshTools_MeshAlgoType_Delabella:
aAlgoFactory = new BRepMesh_DelabellaMeshAlgoFactory();
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

@ -25,7 +25,7 @@ class BRepMesh_Context : public IMeshTools_Context
public:
//! Constructor.
Standard_EXPORT BRepMesh_Context ();
Standard_EXPORT BRepMesh_Context (IMeshTools_MeshAlgoType theMeshType = IMeshTools_MeshAlgoType_DEFAULT);
//! Destructor.
Standard_EXPORT virtual ~BRepMesh_Context ();

View File

@ -25,7 +25,7 @@
class BRepMesh_DataStructureOfDelaun;
//! Class provides base fuctionality to build face triangulation using custom triangulation algorithm.
//! Class provides base functionality to build face triangulation using custom triangulation algorithm.
//! Performs generation of mesh using raw data from model.
class BRepMesh_CustomBaseMeshAlgo : public BRepMesh_ConstrainedBaseMeshAlgo
{
@ -46,19 +46,42 @@ public:
protected:
//! Generates mesh for the contour stored in data structure.
Standard_EXPORT virtual void generateMesh () Standard_OVERRIDE
Standard_EXPORT virtual void generateMesh (const Message_ProgressRange& theRange) 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 ();
postProcessMesh (aMesher);
postProcessMesh (aMesher, theRange);
}
protected:

View File

@ -19,7 +19,7 @@
class BRepMesh_DataStructureOfDelaun;
class BRepMesh_Delaun;
//! Class provides base fuctionality to build face triangulation using custom
//! Class provides base functionality to build face triangulation using custom
//! triangulation algorithm with possibility to modify final mesh.
//! Performs generation of mesh using raw data from model.
template<class BaseAlgo>
@ -39,14 +39,15 @@ public:
protected:
//! Perfroms processing of generated mesh.
virtual void postProcessMesh(BRepMesh_Delaun& theMesher)
//! Performs processing of generated mesh.
virtual void postProcessMesh (BRepMesh_Delaun& theMesher,
const Message_ProgressRange& theRange)
{
BaseAlgo::postProcessMesh (theMesher);
const Handle(BRepMesh_DataStructureOfDelaun)& aStructure = this->getStructure();
std::pair<Standard_Integer, Standard_Integer> aCellsCount = this->getCellsCount (aStructure->NbNodes());
theMesher.InitCirclesTool (aCellsCount.first, aCellsCount.second);
BaseAlgo::postProcessMesh (theMesher, theRange);
}
};

View File

@ -0,0 +1,193 @@
// 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 <Message.hxx>
#include <string.h>
#include <stdarg.h>
#include "delabella.pxx"
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_DelabellaBaseMeshAlgo, BRepMesh_CustomBaseMeshAlgo)
namespace
{
//! Redirect algorithm messages to OCCT messenger.
static int logDelabella2Occ (void* theStream, const char* theFormat, ...)
{
(void )theStream;
char aBuffer[1024]; // should be more than enough for Delabella messages
va_list anArgList;
va_start(anArgList, theFormat);
Vsprintf(aBuffer, theFormat, anArgList);
va_end(anArgList);
Message_Gravity aGravity = Message_Warning;
switch ((int )theFormat[1])
{
case int('E'): aGravity = Message_Fail; break; // [ERR]
case int('W'): aGravity = Message_Trace; break; // [WRN]
case int('N'): aGravity = Message_Trace; break; // [NFO]
}
Message::Send (aBuffer, aGravity);
return 0;
}
}
//=======================================================================
// 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();
if (aTriangulator == NULL) // should never happen
{
throw Standard_ProgramError ("BRepMesh_DelabellaBaseMeshAlgo::buildBaseTriangulation: unable creating a triangulation algorithm");
}
aTriangulator->SetErrLog (logDelabella2Occ, NULL);
try
{
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 ();
aTriangulator = NULL;
}
catch (Standard_Failure const& theException)
{
if (aTriangulator != NULL)
{
aTriangulator->Destroy ();
aTriangulator = NULL;
}
throw Standard_Failure (theException);
}
catch (...)
{
if (aTriangulator != NULL)
{
aTriangulator->Destroy ();
aTriangulator = NULL;
}
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 functionality 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_RTTIEXT(BRepMesh_DelabellaBaseMeshAlgo, BRepMesh_CustomBaseMeshAlgo)
protected:
//! Builds base triangulation using Delabella project.
Standard_EXPORT virtual void buildBaseTriangulation() Standard_OVERRIDE;
};
#endif

View File

@ -0,0 +1,145 @@
// 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;
};
}
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_DelabellaMeshAlgoFactory, IMeshTools_MeshAlgoFactory)
//=======================================================================
// 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 complexity 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_RTTIEXT(BRepMesh_DelabellaMeshAlgoFactory, IMeshTools_MeshAlgoFactory)
};
#endif

View File

@ -90,9 +90,10 @@ 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),
myInitCircles (Standard_False)
{
memset (mySupVert, 0, sizeof (mySupVert));
if (isFillCircles)
{
InitCirclesTool (theCellsCountU, theCellsCountV);
@ -105,9 +106,10 @@ 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),
myInitCircles (Standard_False)
{
memset (mySupVert, 0, sizeof (mySupVert));
if ( theVertices.Length() > 2 )
{
myMeshData = new BRepMesh_DataStructureOfDelaun(
@ -126,9 +128,10 @@ 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),
myInitCircles (Standard_False)
{
memset (mySupVert, 0, sizeof (mySupVert));
if ( theVertices.Length() > 2 )
{
Init( theVertices );
@ -144,9 +147,10 @@ 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),
myInitCircles (Standard_False)
{
memset (mySupVert, 0, sizeof (mySupVert));
perform(theVertexIndices);
}
@ -160,9 +164,10 @@ 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),
myInitCircles (Standard_False)
{
memset (mySupVert, 0, sizeof (mySupVert));
perform (theVertexIndices, theCellsCountU, theCellsCountV);
}
@ -240,6 +245,8 @@ void BRepMesh_Delaun::initCirclesTool (const Bnd_Box2d& theBox,
myCircles.SetMinMaxSize( gp_XY( aMinX, aMinY ), gp_XY( aMaxX, aMaxY ) );
myCircles.SetCellSize ( aDeltaX / Max (theCellsCountU, aScaler),
aDeltaY / Max (theCellsCountV, aScaler));
myInitCircles = Standard_True;
}
//=======================================================================
@ -290,14 +297,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];
@ -324,7 +331,7 @@ void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox)
void BRepMesh_Delaun::deleteTriangle(const Standard_Integer theIndex,
IMeshData::MapOfIntegerInteger& theLoopEdges )
{
if (!myCircles.IsEmpty())
if (myInitCircles)
{
myCircles.Delete (theIndex);
}
@ -373,12 +380,25 @@ void BRepMesh_Delaun::compute(IMeshData::VectorOfInteger& theVertexIndexes)
createTrianglesOnNewVertices (theVertexIndexes, Message_ProgressRange());
}
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)
BRepMesh_SelectorOfDataStructureOfDelaun aSelector (myMeshData);
for (Standard_Integer aSupVertId = 0; aSupVertId < mySupVert.Size(); ++aSupVertId)
aSelector.NeighboursOfNode( mySupVert[aSupVertId] );
aLoopEdges.Clear();
IMeshData::IteratorOfMapOfInteger aFreeTriangles( aSelector.Elements() );
for ( ; aFreeTriangles.More(); aFreeTriangles.Next() )
deleteTriangle( aFreeTriangles.Key(), aLoopEdges );
@ -393,7 +413,7 @@ void BRepMesh_Delaun::compute(IMeshData::VectorOfInteger& theVertexIndexes)
}
// The tops of the super triangle are destroyed
for (Standard_Integer aSupVertId = 0; aSupVertId < 3; ++aSupVertId)
for (Standard_Integer aSupVertId = 0; aSupVertId < mySupVert.Size (); ++aSupVertId)
myMeshData->RemoveNode( mySupVert[aSupVertId] );
}
@ -786,9 +806,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;
}
@ -1246,11 +1264,15 @@ void BRepMesh_Delaun::addTriangle( const Standard_Integer (&theEdgesId)[3],
myMeshData->AddElement(BRepMesh_Triangle(theEdgesId,
theEdgesOri, BRepMesh_Free));
Standard_Boolean isAdded = myCircles.Bind(
aNewTriangleId,
GetVertex( theNodesId[0] ).Coord(),
GetVertex( theNodesId[1] ).Coord(),
GetVertex( theNodesId[2] ).Coord() );
Standard_Boolean isAdded = Standard_True;
if (myInitCircles)
{
isAdded = myCircles.Bind(
aNewTriangleId,
GetVertex( theNodesId[0] ).Coord(),
GetVertex( theNodesId[1] ).Coord(),
GetVertex( theNodesId[2] ).Coord() );
}
if ( !isAdded )
myMeshData->RemoveElement( aNewTriangleId );

View File

@ -149,6 +149,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
@ -353,13 +364,27 @@ private:
//! Performs insertion of internal edges into mesh.
void insertInternalEdges();
//! Checks whether the given vertex id relates to super contour.
Standard_Boolean isSupVertex (const Standard_Integer theVertexIdx) const
{
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;
Standard_Boolean myInitCircles;
BRepMesh_Triangle mySupTrian;
};
#endif

View File

@ -23,7 +23,7 @@
class BRepMesh_DataStructureOfDelaun;
class BRepMesh_Delaun;
//! Class provides base fuctionality to build face triangulation using Dealunay approach.
//! Class provides base functionality to build face triangulation using Dealunay approach.
//! Performs generation of mesh using raw data from model.
class BRepMesh_DelaunayBaseMeshAlgo : public BRepMesh_ConstrainedBaseMeshAlgo
{

View File

@ -46,7 +46,7 @@ public:
protected:
//! Perfroms processing of generated mesh. Generates surface nodes and inserts them into structure.
//! Performs processing of generated mesh. Generates surface nodes and inserts them into structure.
virtual void postProcessMesh (BRepMesh_Delaun& theMesher,
const Message_ProgressRange& theRange) Standard_OVERRIDE
{

View File

@ -84,7 +84,7 @@ protected:
&this->getRangeSplitter());
}
//! Perfroms processing of generated mesh. Generates surface nodes and inserts them into structure.
//! Performs processing of generated mesh. Generates surface nodes and inserts them into structure.
virtual void postProcessMesh (BRepMesh_Delaun& theMesher,
const Message_ProgressRange& theRange) Standard_OVERRIDE
{

View File

@ -88,7 +88,7 @@ BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh()
//=======================================================================
void BRepMesh_IncrementalMesh::Perform(const Message_ProgressRange& theRange)
{
Handle(BRepMesh_Context) aContext = new BRepMesh_Context;
Handle(BRepMesh_Context) aContext = new BRepMesh_Context (myParameters.MeshAlgo);
Perform (aContext, theRange);
}

View File

@ -22,7 +22,7 @@
#include <IMeshTools_MeshAlgoFactory.hxx>
//! Default implementation of IMeshTools_MeshAlgoFactory providing algorithms
//! of different compexity depending on type of target surface.
//! of different complexity depending on type of target surface.
class BRepMesh_MeshAlgoFactory : public IMeshTools_MeshAlgoFactory
{
public:

View File

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

1043
src/BRepMesh/delabella.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
/*
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.
*/
#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

@ -2,6 +2,7 @@ IMeshTools_Context.hxx
IMeshTools_CurveTessellator.hxx
IMeshTools_MeshAlgo.hxx
IMeshTools_MeshAlgoFactory.hxx
IMeshTools_MeshAlgoType.hxx
IMeshTools_MeshBuilder.hxx
IMeshTools_MeshBuilder.cxx
IMeshTools_ModelAlgo.hxx

View File

@ -0,0 +1,25 @@
// Copyright (c) 2020 OPEN CASCADE SAS
//
// 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 _IMeshTools_MeshAlgoType_HeaderFile
#define _IMeshTools_MeshAlgoType_HeaderFile
//! Enumerates built-in meshing algorithms factories implementing IMeshTools_MeshAlgoFactory interface.
enum IMeshTools_MeshAlgoType
{
IMeshTools_MeshAlgoType_DEFAULT = -1, //!< use global default (IMeshTools_MeshAlgoType_Watson or CSF_MeshAlgo)
IMeshTools_MeshAlgoType_Watson = 0, //!< generate 2D Delaunay triangulation based on Watson algorithm (BRepMesh_MeshAlgoFactory)
IMeshTools_MeshAlgoType_Delabella, //!< generate 2D Delaunay triangulation based on Delabella algorithm (BRepMesh_DelabellaMeshAlgoFactory)
};
#endif

View File

@ -16,6 +16,7 @@
#ifndef _IMeshTools_Parameters_HeaderFile
#define _IMeshTools_Parameters_HeaderFile
#include <IMeshTools_MeshAlgoType.hxx>
#include <Precision.hxx>
//! Structure storing meshing parameters
@ -24,6 +25,7 @@ struct IMeshTools_Parameters {
//! Default constructor
IMeshTools_Parameters ()
:
MeshAlgo (IMeshTools_MeshAlgoType_DEFAULT),
Angle(0.5),
Deflection(0.001),
AngleInterior(-1.0),
@ -47,6 +49,9 @@ struct IMeshTools_Parameters {
return 0.1;
}
//! 2D Delaunay triangulation algorithm factory to use
IMeshTools_MeshAlgoType MeshAlgo;
//! Angular deflection used to tessellate the boundary edges
Standard_Real Angle;

View File

@ -43,6 +43,11 @@
#include <TopExp_Explorer.hxx>
#include <TopTools_MapIteratorOfMapOfShape.hxx>
#include <BRepMesh_Context.hxx>
#include <BRepMesh_FaceDiscret.hxx>
#include <BRepMesh_MeshAlgoFactory.hxx>
#include <BRepMesh_DelabellaMeshAlgoFactory.hxx>
//epa Memory leaks test
//OAN: for triepoints
#ifdef _WIN32
@ -94,7 +99,8 @@ options:\n\
-adjust_min enables local adjustment of min size depending on edge size (switched off by default)\n\
-force_face_def disables usage of shape tolerances for computing face deflection (switched off by default)\n\
-decrease enforces the meshing of the shape even if current mesh satisfies the new criteria\
(switched off by default).\n";
(switched off by default).\n\
-algo {watson|delabella} changes core triangulation algorithm to one with specified id (watson is used by default)\n";
return 0;
}
@ -109,6 +115,7 @@ options:\n\
aMeshParams.Deflection = aMeshParams.DeflectionInterior =
Max(Draw::Atof(argv[2]), Precision::Confusion());
Handle (IMeshTools_Context) aContext = new BRepMesh_Context;
if (nbarg > 3)
{
Standard_Integer i = 3;
@ -135,23 +142,54 @@ options:\n\
aMeshParams.AllowQualityDecrease = Standard_True;
else if (i < nbarg)
{
Standard_Real aVal = Draw::Atof(argv[i++]);
if (aOpt == "-a")
if (aOpt == "-algo")
{
aMeshParams.Angle = aVal * M_PI / 180.;
}
else if (aOpt == "-ai")
{
aMeshParams.AngleInterior = aVal * M_PI / 180.;
}
else if (aOpt == "-min")
aMeshParams.MinSize = aVal;
else if (aOpt == "-di")
{
aMeshParams.DeflectionInterior = aVal;
TCollection_AsciiString anAlgoStr (argv[i++]);
anAlgoStr.LowerCase();
if (anAlgoStr == "watson"
|| anAlgoStr == "0")
{
aMeshParams.MeshAlgo = IMeshTools_MeshAlgoType_Watson;
aContext->SetFaceDiscret (new BRepMesh_FaceDiscret (new BRepMesh_MeshAlgoFactory));
}
else if (anAlgoStr == "delabella"
|| anAlgoStr == "1")
{
aMeshParams.MeshAlgo = IMeshTools_MeshAlgoType_Delabella;
aContext->SetFaceDiscret (new BRepMesh_FaceDiscret (new BRepMesh_DelabellaMeshAlgoFactory));
}
else if (anAlgoStr == "-1"
|| anAlgoStr == "default")
{
// already handled by BRepMesh_Context constructor
//aMeshParams.MeshAlgo = IMeshTools_MeshAlgoType_DEFAULT;
}
else
{
di << "Syntax error at " << anAlgoStr;
return 1;
}
}
else
--i;
{
Standard_Real aVal = Draw::Atof(argv[i++]);
if (aOpt == "-a")
{
aMeshParams.Angle = aVal * M_PI / 180.;
}
else if (aOpt == "-ai")
{
aMeshParams.AngleInterior = aVal * M_PI / 180.;
}
else if (aOpt == "-min")
aMeshParams.MinSize = aVal;
else if (aOpt == "-di")
{
aMeshParams.DeflectionInterior = aVal;
}
else
--i;
}
}
}
}
@ -160,7 +198,11 @@ options:\n\
<< (aMeshParams.InParallel ? "ON" : "OFF") << "\n";
Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator(di, 1);
BRepMesh_IncrementalMesh aMesher (aShape, aMeshParams, aProgress->Start());
BRepMesh_IncrementalMesh aMesher;
aMesher.SetShape (aShape);
aMesher.ChangeParameters() = aMeshParams;
aMesher.Perform (aContext, aProgress->Start());
di << "Meshing statuses: ";
const Standard_Integer aStatus = aMesher.GetStatusFlags();

View File

@ -133,3 +133,9 @@ int Sprintf (char* theBuffer, const char* theFormat, ...)
va_end(argp);
return result;
}
int Vsprintf (char* theBuffer, const char* theFormat, va_list theArgList)
{
SAVE_TL();
return vsprintf_l(theBuffer, Standard_CLocaleSentry::GetCLocale(), theFormat, theArgList);
}

View File

@ -85,6 +85,15 @@ Standard_EXPORT int Fprintf (FILE* theFile, const char* theFormat, ...);
//! Equivalent of standard C function sprintf() that always uses C locale
Standard_EXPORT int Sprintf (char* theBuffer, const char* theFormat, ...);
//! Equivalent of standard C function vsprintf() that always uses C locale.
//! Note that this function does not check buffer bounds and should be used with precaution measures
//! (only with format fitting into the buffer of known size).
//! @param theBuffer [in] [out] string buffer to fill
//! @param theFormat [in] format to apply
//! @param theArgList [in] argument list for specified format
//! @return the total number of characters written, or a negative number on error
Standard_EXPORT int Vsprintf (char* theBuffer, const char* theFormat, va_list theArgList);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -0,0 +1,24 @@
puts "========"
puts "0028089: Mesh - New algorithm for triangulation of 2d polygons"
puts "========"
puts ""
pload MODELING VISUALIZATION
restore [locate_data_file terrain.brep] t1
tclean t1
#tscale t1 0 0 0 0.01
tcopy t1 t2
ttranslate t1 0 0 0
ttranslate t2 8000 0 0
incmesh t1 1000 -algo 0 -a 50
trinfo t1
incmesh t2 1000 -algo 1 -a 50
trinfo t2
vclear
vinit View1
vtop
vdefaults -autotriang 0
vdisplay -dispMode 1 t1 t2
vfit
vaspects t1 -drawEdges 1
vaspects t2 -drawEdges 1

View File

@ -0,0 +1,27 @@
puts "========"
puts "0028089: Mesh - New algorithm for triangulation of 2d polygons"
puts "========"
puts ""
pload MODELING VISUALIZATION
psphere s1 1
psphere s2 1
box b1 0 2 0 1 2 2
box b2 2 2 0 1 2 2
ttranslate s2 2 0 0
incmesh s1 0.5 -algo 0 -a 50
incmesh s2 0.5 -algo 1 -a 50
incmesh b1 0.5 -algo 0
incmesh b2 0.5 -algo 1
vclear
vinit View1
vdefaults -autotriang 0
vdisplay -dispMode 1 s1 s2 b1 b2
vfit
vaspects s1 -drawEdges 1
vaspects s2 -drawEdges 1
vaspects b1 -drawEdges 1
vaspects b2 -drawEdges 1
vdump ${imagedir}/${casename}.png