mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-26 10:19:45 +03:00
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.
194 lines
6.1 KiB
C++
194 lines
6.1 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 <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");
|
|
}
|
|
}
|