This chapter represents documentation about hole triangulations or stitching two holes. More...
Classes | |
| struct | MR::FillHoleParams |
| Parameters structure for MR::fillHole Structure has some options to control MR::fillHole. More... | |
| struct | MR::StitchHolesParams |
| Parameters structure for MR::stitchHoles Structure has some options to control MR::stitchHoles. More... | |
| struct | MR::FillHoleItem |
| struct | MR::HoleFillPlan |
| concise representation of proposed hole triangulation More... | |
| struct | MR::MakeBridgeResult |
| struct | MR::FillHoleMetric |
| Holds metrics for fillHole and stitchHoles triangulation . More... | |
Typedefs | |
| using | MR::FillTriangleMetric = std::function<double( VertId a, VertId b, VertId c )> |
| args: three vertices of candidate triangle | |
| using | MR::FillEdgeMetric = std::function<double( VertId a, VertId b, VertId l, VertId r )> |
| using | MR::FillCombineMetric = std::function<double( double, double )> |
| args: two metric weights to combine (usualy it is simple sum of them) | |
Functions | |
| void | MR::stitchHoles (Mesh &mesh, EdgeId a, EdgeId b, const StitchHolesParams ¶ms={}) |
| Stitches two holes in Mesh . | |
| void | MR::buildCylinderBetweenTwoHoles (Mesh &mesh, EdgeId a, EdgeId b, const StitchHolesParams ¶ms={}) |
| bool | MR::stitchHoles (Mesh &mesh, const StitchHolesParams ¶ms={}) |
| this version finds holes in the mesh by itself and returns false if they are not found | |
| bool | MR::buildCylinderBetweenTwoHoles (Mesh &mesh, const StitchHolesParams ¶ms={}) |
| void | MR::fillHole (Mesh &mesh, EdgeId a, const FillHoleParams ¶ms={}) |
| Fills hole in mesh . | |
| void | MR::fillHoles (Mesh &mesh, const std::vector< EdgeId > &as, const FillHoleParams ¶ms={}) |
| fill all holes given by their representative edges in | |
| bool | MR::isHoleBd (const MeshTopology &topology, const EdgeLoop &loop) |
| HoleFillPlan | MR::getHoleFillPlan (const Mesh &mesh, EdgeId e, const FillHoleParams ¶ms={}) |
| std::vector< HoleFillPlan > | MR::getHoleFillPlans (const Mesh &mesh, const std::vector< EdgeId > &holeRepresentativeEdges, const FillHoleParams ¶ms={}) |
| HoleFillPlan | MR::getPlanarHoleFillPlan (const Mesh &mesh, EdgeId e) |
| std::vector< HoleFillPlan > | MR::getPlanarHoleFillPlans (const Mesh &mesh, const std::vector< EdgeId > &holeRepresentativeEdges) |
| void | MR::executeHoleFillPlan (Mesh &mesh, EdgeId a0, HoleFillPlan &plan, FaceBitSet *outNewFaces=nullptr) |
| quickly triangulates the face or hole to the left of (e) given the plan (quickly compared to fillHole function) | |
| VertId | MR::fillHoleTrivially (Mesh &mesh, EdgeId a, FaceBitSet *outNewFaces=nullptr) |
| Triangulates face of hole in mesh trivially . | |
| EdgeId | MR::extendHole (Mesh &mesh, EdgeId a, const Plane3f &plane, FaceBitSet *outNewFaces=nullptr) |
| std::vector< EdgeId > | MR::extendAllHoles (Mesh &mesh, const Plane3f &plane, FaceBitSet *outNewFaces=nullptr) |
| EdgeId | MR::extendHole (Mesh &mesh, EdgeId a, std::function< Vector3f(const Vector3f &)> getVertPos, FaceBitSet *outNewFaces=nullptr) |
| EdgeId | MR::buildBottom (Mesh &mesh, EdgeId a, Vector3f dir, float holeExtension, FaceBitSet *outNewFaces=nullptr) |
| EdgeId | MR::makeDegenerateBandAroundHole (Mesh &mesh, EdgeId a, FaceBitSet *outNewFaces=nullptr) |
| MakeBridgeResult | MR::makeQuadBridge (MeshTopology &topology, EdgeId a, EdgeId b, FaceBitSet *outNewFaces=nullptr) |
| MakeBridgeResult | MR::makeBridge (MeshTopology &topology, EdgeId a, EdgeId b, FaceBitSet *outNewFaces=nullptr) |
| MakeBridgeResult | MR::makeSmoothBridge (Mesh &mesh, EdgeId a, EdgeId b, float samplingStep, FaceBitSet *outNewFaces=nullptr) |
| EdgeId | MR::makeBridgeEdge (MeshTopology &topology, EdgeId a, EdgeId b) |
| void | MR::splitQuad (MeshTopology &topology, EdgeId a, FaceBitSet *outNewFaces=nullptr) |
| given quadrangle face to the left of a, splits it in two triangles with new diagonal edge via dest(a) | |
| double | MR::calcCombinedFillMetric (const Mesh &mesh, const FaceBitSet &filledRegion, const FillHoleMetric &metric) |
| Computes combined metric after filling a hole. | |
| FillHoleMetric | MR::getCircumscribedMetric (const Mesh &mesh) |
| FillHoleMetric | MR::getPlaneFillMetric (const Mesh &mesh, EdgeId e) |
| FillHoleMetric | MR::getPlaneNormalizedFillMetric (const Mesh &mesh, EdgeId e) |
| FillHoleMetric | MR::getComplexStitchMetric (const Mesh &mesh) |
| FillHoleMetric | MR::getEdgeLengthFillMetric (const Mesh &mesh) |
| Simple metric minimizing the sum of all edge lengths. | |
| FillHoleMetric | MR::getEdgeLengthStitchMetric (const Mesh &mesh) |
| FillHoleMetric | MR::getVerticalStitchMetric (const Mesh &mesh, const Vector3f &upDir) |
| FillHoleMetric | MR::getVerticalStitchMetricEdgeBased (const Mesh &mesh, const Vector3f &upDir) |
| FillHoleMetric | MR::getComplexFillMetric (const Mesh &mesh, EdgeId e) |
| FillHoleMetric | MR::getParallelPlaneFillMetric (const Mesh &mesh, EdgeId e, const Plane3f *plane=nullptr) |
| This metric minimizes summary projection of new edges to plane normal, (try do produce edges parallel to plane) | |
| FillHoleMetric | MR::getMaxDihedralAngleMetric (const Mesh &mesh) |
| FillHoleMetric | MR::getUniversalMetric (const Mesh &mesh) |
| FillHoleMetric | MR::getMinTriAngleMetric (const Mesh &mesh) |
| This metric maximizes the minimal angle among all faces in the triangulation. | |
| FillHoleMetric | MR::getMinAreaMetric (const Mesh &mesh) |
Variables | |
| const double | MR::BadTriangulationMetric |
This chapter represents documentation about hole triangulations or stitching two holes.
| using MR::FillCombineMetric = std::function<double( double, double )> |
#include <MRMesh/MRMeshMetrics.h>
args: two metric weights to combine (usualy it is simple sum of them)
| using MR::FillEdgeMetric = std::function<double( VertId a, VertId b, VertId l, VertId r )> |
#include <MRMesh/MRMeshMetrics.h>
args: a->b: candidate edge l: next(a->b) note that they are not connected in topology untill triangulation process ends r: prev(a->b) note that they are not connected in topology untill triangulation process ends
| using MR::FillTriangleMetric = std::function<double( VertId a, VertId b, VertId c )> |
#include <MRMesh/MRMeshMetrics.h>
args: three vertices of candidate triangle
| EdgeId MR::buildBottom | ( | Mesh & | mesh, |
| EdgeId | a, | ||
| Vector3f | dir, | ||
| float | holeExtension, | ||
| FaceBitSet * | outNewFaces = nullptr ) |
#include <MRMesh/MRMeshFillHole.h>
adds cylindrical extension of given hole represented by one of its edges (having no valid left face) by adding new vertices located in lowest point of the hole -dir*holeExtension and 2 * number_of_hole_edge triangles;
| bool MR::buildCylinderBetweenTwoHoles | ( | Mesh & | mesh, |
| const StitchHolesParams & | params = {} ) |
#include <MRMesh/MRMeshFillHole.h>
| void MR::buildCylinderBetweenTwoHoles | ( | Mesh & | mesh, |
| EdgeId | a, | ||
| EdgeId | b, | ||
| const StitchHolesParams & | params = {} ) |
#include <MRMesh/MRMeshFillHole.h>
| double MR::calcCombinedFillMetric | ( | const Mesh & | mesh, |
| const FaceBitSet & | filledRegion, | ||
| const FillHoleMetric & | metric ) |
#include <MRMesh/MRMeshMetrics.h>
Computes combined metric after filling a hole.
| void MR::executeHoleFillPlan | ( | Mesh & | mesh, |
| EdgeId | a0, | ||
| HoleFillPlan & | plan, | ||
| FaceBitSet * | outNewFaces = nullptr ) |
#include <MRMesh/MRMeshFillHole.h>
quickly triangulates the face or hole to the left of (e) given the plan (quickly compared to fillHole function)
| std::vector< EdgeId > MR::extendAllHoles | ( | Mesh & | mesh, |
| const Plane3f & | plane, | ||
| FaceBitSet * | outNewFaces = nullptr ) |
#include <MRMesh/MRMeshFillHole.h>
adds cylindrical extension of too all holes of the mesh by calling extendHole(...);
| EdgeId MR::extendHole | ( | Mesh & | mesh, |
| EdgeId | a, | ||
| const Plane3f & | plane, | ||
| FaceBitSet * | outNewFaces = nullptr ) |
#include <MRMesh/MRMeshFillHole.h>
adds cylindrical extension of given hole represented by one of its edges (having no valid left face) by adding new vertices located in given plane and 2 * number_of_hole_edge triangles;
| EdgeId MR::extendHole | ( | Mesh & | mesh, |
| EdgeId | a, | ||
| std::function< Vector3f(const Vector3f &)> | getVertPos, | ||
| FaceBitSet * | outNewFaces = nullptr ) |
#include <MRMesh/MRMeshFillHole.h>
adds extension of given hole represented by one of its edges (having no valid left face) by adding new vertices located at getVertPos( existing vertex position );
| void MR::fillHole | ( | Mesh & | mesh, |
| EdgeId | a, | ||
| const FillHoleParams & | params = {} ) |
#include <MRMesh/MRMeshFillHole.h>
Fills hole in mesh
.
Fills given hole represented by one of its edges (having no valid left face),
uses fillHoleTrivially if cannot fill hole without multiple edges,
default metric: CircumscribedFillMetric
Next picture show, how newly generated faces can be smoothed MR::positionVertsSmoothly MR::subdivideMesh
| mesh | mesh with hole |
| a | EdgeId which represents hole (should not have valid left FaceId) |
| params | parameters of hole filling |
| void MR::fillHoles | ( | Mesh & | mesh, |
| const std::vector< EdgeId > & | as, | ||
| const FillHoleParams & | params = {} ) |
#include <MRMesh/MRMeshFillHole.h>
fill all holes given by their representative edges in
| as |
| VertId MR::fillHoleTrivially | ( | Mesh & | mesh, |
| EdgeId | a, | ||
| FaceBitSet * | outNewFaces = nullptr ) |
#include <MRMesh/MRMeshFillHole.h>
Triangulates face of hole in mesh trivially
.
Fills given hole represented by one of its edges (having no valid left face)
by creating one new vertex in the centroid of boundary vertices and connecting new vertex with all boundary vertices.
Next picture show, how newly generated faces can be smoothed MR::positionVertsSmoothly MR::subdivideMesh
| mesh | mesh with hole |
| a | EdgeId points on the face or hole to the left that will be triangulated |
| outNewFaces | optional output newly generated faces |
| FillHoleMetric MR::getCircumscribedMetric | ( | const Mesh & | mesh | ) |
#include <MRMesh/MRMeshMetrics.h>
This metric minimizes the sum of circumcircle radii for all triangles in the triangulation. It is rather fast to calculate, and it results in typically good triangulations.
| FillHoleMetric MR::getComplexFillMetric | ( | const Mesh & | mesh, |
| EdgeId | e ) |
#include <MRMesh/MRMeshMetrics.h>
This metric minimizes the sum of triangleMetric for all triangles in the triangulation plus the sum edgeMetric for all edges inside and on the boundary of the triangulation.
Where
triangleMetric is proportional to weighted triangle area and triangle aspect ratio
edgeMetric grows with angle between triangles as ( ( 1 - cos( x ) ) / ( 1 + cos( x ) ) ) ^ 4.
| FillHoleMetric MR::getComplexStitchMetric | ( | const Mesh & | mesh | ) |
#include <MRMesh/MRMeshMetrics.h>
This metric minimizes the sum of triangleMetric for all triangles in the triangulation plus the sum edgeMetric for all edges inside and on the boundary of the triangulation.
Where
triangleMetric is proportional to triangle aspect ratio
edgeMetric is proportional to ( 1 - dihedralAngleCos )
| FillHoleMetric MR::getEdgeLengthFillMetric | ( | const Mesh & | mesh | ) |
#include <MRMesh/MRMeshMetrics.h>
Simple metric minimizing the sum of all edge lengths.
| FillHoleMetric MR::getEdgeLengthStitchMetric | ( | const Mesh & | mesh | ) |
#include <MRMesh/MRMeshMetrics.h>
Forbids connecting vertices from the same hole
Simple metric minimizing edge length
| HoleFillPlan MR::getHoleFillPlan | ( | const Mesh & | mesh, |
| EdgeId | e, | ||
| const FillHoleParams & | params = {} ) |
#include <MRMesh/MRMeshFillHole.h>
prepares the plan how to triangulate the face or hole to the left of (e) (not filling it immediately), several getHoleFillPlan can work in parallel
| std::vector< HoleFillPlan > MR::getHoleFillPlans | ( | const Mesh & | mesh, |
| const std::vector< EdgeId > & | holeRepresentativeEdges, | ||
| const FillHoleParams & | params = {} ) |
#include <MRMesh/MRMeshFillHole.h>
prepares the plans how to triangulate the faces or holes, each given by a boundary edge (with filling target to the left), the plans are prepared in parallel with minimal memory allocation compared to manual calling of several getHoleFillPlan(), but it can inefficient when some holes are very complex
| FillHoleMetric MR::getMaxDihedralAngleMetric | ( | const Mesh & | mesh | ) |
#include <MRMesh/MRMeshMetrics.h>
This metric minimizes the maximal dihedral angle between the faces in the triangulation and on its boundary
| FillHoleMetric MR::getMinAreaMetric | ( | const Mesh & | mesh | ) |
#include <MRMesh/MRMeshMetrics.h>
This metric is for triangulation construction with minimal summed area of triangles. Warning: this metric can produce degenerated triangles
| FillHoleMetric MR::getMinTriAngleMetric | ( | const Mesh & | mesh | ) |
#include <MRMesh/MRMeshMetrics.h>
This metric maximizes the minimal angle among all faces in the triangulation.
| FillHoleMetric MR::getParallelPlaneFillMetric | ( | const Mesh & | mesh, |
| EdgeId | e, | ||
| const Plane3f * | plane = nullptr ) |
#include <MRMesh/MRMeshMetrics.h>
This metric minimizes summary projection of new edges to plane normal, (try do produce edges parallel to plane)
| HoleFillPlan MR::getPlanarHoleFillPlan | ( | const Mesh & | mesh, |
| EdgeId | e ) |
#include <MRMesh/MRMeshFillHole.h>
prepares the plan how to triangulate the planar face or planar hole to the left of (e) (not filling it immediately), several getPlanarHoleFillPlan can work in parallel
| std::vector< HoleFillPlan > MR::getPlanarHoleFillPlans | ( | const Mesh & | mesh, |
| const std::vector< EdgeId > & | holeRepresentativeEdges ) |
#include <MRMesh/MRMeshFillHole.h>
prepares the plans how to triangulate the planar faces or holes, each given by a boundary edge (with filling target to the left), the plans are prepared in parallel with minimal memory allocation compared to manual calling of several getPlanarHoleFillPlan(), but it can inefficient when some holes are very complex
| FillHoleMetric MR::getPlaneFillMetric | ( | const Mesh & | mesh, |
| EdgeId | e ) |
#include <MRMesh/MRMeshMetrics.h>
Same as getCircumscribedFillMetric, but with extra penalty for the triangles having normals looking in the opposite side of plane containing left of (e).
| FillHoleMetric MR::getPlaneNormalizedFillMetric | ( | const Mesh & | mesh, |
| EdgeId | e ) |
#include <MRMesh/MRMeshMetrics.h>
Similar to getPlaneFillMetric with extra penalty for the triangles having normals looking in the opposite side of plane containing left of (e), but the metric minimizes the sum of circumcircle radius times aspect ratio for all triangles in the triangulation.
| FillHoleMetric MR::getUniversalMetric | ( | const Mesh & | mesh | ) |
#include <MRMesh/MRMeshMetrics.h>
This metric consists of two parts 1) for each triangle: it is the circumcircle diameter, this avoids the appearance of degenerate triangles; 2) for each edge: square root of double total area of triangles to its left and right times the factor depending extensionally on absolute dihedral angle between left and right triangles, this makes visually triangulated surface as smooth as possible. For planar holes it is the same as getCircumscribedMetric.
| FillHoleMetric MR::getVerticalStitchMetric | ( | const Mesh & | mesh, |
| const Vector3f & | upDir ) |
#include <MRMesh/MRMeshMetrics.h>
Forbids connecting vertices from the same hole
penalize for large area and face normal deviation from upDir
All new faces should be parallel to given direction
| FillHoleMetric MR::getVerticalStitchMetricEdgeBased | ( | const Mesh & | mesh, |
| const Vector3f & | upDir ) |
#include <MRMesh/MRMeshMetrics.h>
Forbids connecting vertices from the same hole
penalize for long edges and its deviation from upDir
All new faces should be parallel to given direction
|
nodiscard |
#include <MRMesh/MRMeshFillHole.h>
returns true if given loop is a boundary of one hole in given mesh topology:
| MakeBridgeResult MR::makeBridge | ( | MeshTopology & | topology, |
| EdgeId | a, | ||
| EdgeId | b, | ||
| FaceBitSet * | outNewFaces = nullptr ) |
#include <MRMesh/MRMeshFillHole.h>
creates a bridge between two boundary edges a and b (both having no valid left face); bridge consists of two triangles in general or of one triangle if a and b are neighboring edges on the boundary;
| EdgeId MR::makeBridgeEdge | ( | MeshTopology & | topology, |
| EdgeId | a, | ||
| EdgeId | b ) |
#include <MRMesh/MRMeshFillHole.h>
creates a new bridge edge between origins of two boundary edges a and b (both having no valid left face);
| EdgeId MR::makeDegenerateBandAroundHole | ( | Mesh & | mesh, |
| EdgeId | a, | ||
| FaceBitSet * | outNewFaces = nullptr ) |
#include <MRMesh/MRMeshFillHole.h>
creates a band of degenerate triangles around given hole;
| MakeBridgeResult MR::makeQuadBridge | ( | MeshTopology & | topology, |
| EdgeId | a, | ||
| EdgeId | b, | ||
| FaceBitSet * | outNewFaces = nullptr ) |
#include <MRMesh/MRMeshFillHole.h>
creates a bridge between two boundary edges a and b (both having no valid left face); bridge consists of one quadrangle in general (beware that it cannot be rendered) or of one triangle if a and b are neighboring edges on the boundary;
| MakeBridgeResult MR::makeSmoothBridge | ( | Mesh & | mesh, |
| EdgeId | a, | ||
| EdgeId | b, | ||
| float | samplingStep, | ||
| FaceBitSet * | outNewFaces = nullptr ) |
#include <MRMesh/MRMeshFillHole.h>
creates a bridge between two boundary edges a and b (both having no valid left face); bridge consists of strip of quadrangles (each consisting of two triangles) in general or of some triangles if a and b are neighboring edges on the boundary; the bridge is made as smooth as possible with small angles in between its links and on the boundary with existed triangles;
| samplingStep | boundaries of the bridge will be subdivided until the distance between neighbor points becomes less than this distance |
| void MR::splitQuad | ( | MeshTopology & | topology, |
| EdgeId | a, | ||
| FaceBitSet * | outNewFaces = nullptr ) |
#include <MRMesh/MRMeshFillHole.h>
given quadrangle face to the left of a, splits it in two triangles with new diagonal edge via dest(a)
| bool MR::stitchHoles | ( | Mesh & | mesh, |
| const StitchHolesParams & | params = {} ) |
#include <MRMesh/MRMeshFillHole.h>
this version finds holes in the mesh by itself and returns false if they are not found
| void MR::stitchHoles | ( | Mesh & | mesh, |
| EdgeId | a, | ||
| EdgeId | b, | ||
| const StitchHolesParams & | params = {} ) |
#include <MRMesh/MRMeshFillHole.h>
Stitches two holes in Mesh
.
Build cylindrical patch to fill space between two holes represented by one of their edges each,
default metric: ComplexStitchMetric
Next picture show, how newly generated faces can be smoothed MR::positionVertsSmoothly MR::subdivideMesh
| mesh | mesh with hole |
| a | EdgeId which represents 1st hole (should not have valid left FaceId) |
| b | EdgeId which represents 2nd hole (should not have valid left FaceId) |
| params | parameters of holes stitching |
|
extern |
#include <MRMesh/MRMeshMetrics.h>
Big value, but less then DBL_MAX, to be able to pass some bad triangulations instead of breaking it e10 - real metrics to have weight in triangulation, if it would be more than e15+ some metrics will be less than double precision