1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-19 13:40:49 +03:00
Files
occt/src/BRepMesh/BRepMesh_DelabellaBaseMeshAlgo.cxx
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

156 lines
5.0 KiB
C++

// 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");
}
}