Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
185d29b92This file is pinned to the selected release. Download the original to open it in your design tool.
// 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 <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;
}
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.
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.
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.
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 orientation parameters.
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 contour 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_RTTIEXT(BRepMesh_MeshTool, Standard_Transient)
private:
//! Returns True if the given point lies within circumcircle of the given triangle.
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.
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