mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-04 13:13:25 +03:00
0026338: STL export (especially binary) needs a lot of time if selected export path is not local
Method StlAPI_Writer::Write() is reimplemented to write triangulation directly, without conversion to StlMesh_Mesh. New DRAW command "tessellate" is added to generate rapidly triangulation of prescribed size (on surface). Command "tricheck" is protected to deal correctly with triangulation without UV data. New tests added: perf de bug26338_1 and _2; bugs stlvrml bug26338 Correction of testing environment
This commit is contained in:
@@ -232,6 +232,155 @@ options:\n\
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : tessellate
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static Standard_Integer tessellate (Draw_Interpretor& /*di*/, Standard_Integer nbarg, const char** argv)
|
||||
{
|
||||
if (nbarg != 5)
|
||||
{
|
||||
std::cerr << "Builds regular triangulation with specified number of triangles\n"
|
||||
" Usage: tessellate result {surface|face} nbu nbv\n"
|
||||
" Triangulation is put into the face with natural bounds (result);\n"
|
||||
" it will have 2*nbu*nbv triangles and (nbu+1)*(nbv+1) nodes";
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *aResName = argv[1];
|
||||
const char *aSrcName = argv[2];
|
||||
int aNbU = Draw::Atoi (argv[3]);
|
||||
int aNbV = Draw::Atoi (argv[4]);
|
||||
|
||||
if (aNbU <= 0 || aNbV <= 0)
|
||||
{
|
||||
std::cerr << "Error: Arguments nbu and nbv must be both greater than 0\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Handle(Geom_Surface) aSurf = DrawTrSurf::GetSurface(aSrcName);
|
||||
double aUMin, aUMax, aVMin, aVMax;
|
||||
if (! aSurf.IsNull())
|
||||
{
|
||||
aSurf->Bounds (aUMin, aUMax, aVMin, aVMax);
|
||||
}
|
||||
else
|
||||
{
|
||||
TopoDS_Shape aShape = DBRep::Get(aSrcName);
|
||||
if (aShape.IsNull() || aShape.ShapeType() != TopAbs_FACE)
|
||||
{
|
||||
std::cerr << "Error: " << aSrcName << " is not a face\n";
|
||||
return 1;
|
||||
}
|
||||
TopoDS_Face aFace = TopoDS::Face (aShape);
|
||||
aSurf = BRep_Tool::Surface (aFace);
|
||||
if (aSurf.IsNull())
|
||||
{
|
||||
std::cerr << "Error: Face " << aSrcName << " has no surface\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
BRepTools::UVBounds (aFace, aUMin, aUMax, aVMin, aVMax);
|
||||
}
|
||||
if (Precision::IsInfinite (aUMin) || Precision::IsInfinite (aUMax) ||
|
||||
Precision::IsInfinite (aVMin) || Precision::IsInfinite (aVMax))
|
||||
{
|
||||
std::cerr << "Error: surface has infinite parametric range, aborting\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
BRepBuilderAPI_MakeFace aFaceMaker (aSurf, aUMin, aUMax, aVMin, aVMax, Precision::Confusion());
|
||||
if (! aFaceMaker.IsDone())
|
||||
{
|
||||
std::cerr << "Error: cannot build face with natural bounds, aborting\n";
|
||||
return 1;
|
||||
}
|
||||
TopoDS_Face aFace = aFaceMaker;
|
||||
|
||||
// create triangulation
|
||||
int aNbNodes = (aNbU + 1) * (aNbV + 1);
|
||||
int aNbTriangles = 2 * aNbU * aNbV;
|
||||
Handle(Poly_Triangulation) aTriangulation =
|
||||
new Poly_Triangulation (aNbNodes, aNbTriangles, Standard_False);
|
||||
|
||||
// fill nodes
|
||||
TColgp_Array1OfPnt &aNodes = aTriangulation->ChangeNodes();
|
||||
GeomAdaptor_Surface anAdSurf (aSurf);
|
||||
double aDU = (aUMax - aUMin) / aNbU;
|
||||
double aDV = (aVMax - aVMin) / aNbV;
|
||||
for (int iU = 0, iShift = 1; iU <= aNbU; iU++, iShift += aNbV + 1)
|
||||
{
|
||||
double aU = aUMin + iU * aDU;
|
||||
for (int iV = 0; iV <= aNbV; iV++)
|
||||
{
|
||||
double aV = aVMin + iV * aDV;
|
||||
gp_Pnt aP = anAdSurf.Value (aU, aV);
|
||||
aNodes.SetValue (iShift + iV, aP);
|
||||
}
|
||||
}
|
||||
|
||||
// fill triangles
|
||||
Poly_Array1OfTriangle &aTriangles = aTriangulation->ChangeTriangles();
|
||||
for (int iU = 0, iShift = 1, iTri = 0; iU < aNbU; iU++, iShift += aNbV + 1)
|
||||
{
|
||||
for (int iV = 0; iV < aNbV; iV++)
|
||||
{
|
||||
int iBase = iShift + iV;
|
||||
Poly_Triangle aTri1 (iBase, iBase + aNbV + 2, iBase + 1);
|
||||
Poly_Triangle aTri2 (iBase, iBase + aNbV + 1, iBase + aNbV + 2);
|
||||
aTriangles.SetValue (++iTri, aTri1);
|
||||
aTriangles.SetValue (++iTri, aTri2);
|
||||
}
|
||||
}
|
||||
|
||||
// put triangulation to face
|
||||
BRep_Builder B;
|
||||
B.UpdateFace (aFace, aTriangulation);
|
||||
|
||||
// fill edge polygons
|
||||
TColStd_Array1OfInteger aUMinIso (1, aNbV + 1), aUMaxIso (1, aNbV + 1);
|
||||
for (int iV = 0; iV <= aNbV; iV++)
|
||||
{
|
||||
aUMinIso.SetValue (1 + iV, 1 + iV);
|
||||
aUMaxIso.SetValue (1 + iV, 1 + iV + aNbU * (1 + aNbV));
|
||||
}
|
||||
TColStd_Array1OfInteger aVMinIso (1, aNbU + 1), aVMaxIso (1, aNbU + 1);
|
||||
for (int iU = 0; iU <= aNbU; iU++)
|
||||
{
|
||||
aVMinIso.SetValue (1 + iU, 1 + iU * (1 + aNbV));
|
||||
aVMaxIso.SetValue (1 + iU, (1 + iU) * (1 + aNbV));
|
||||
}
|
||||
Handle(Poly_PolygonOnTriangulation) aUMinPoly = new Poly_PolygonOnTriangulation (aUMinIso);
|
||||
Handle(Poly_PolygonOnTriangulation) aUMaxPoly = new Poly_PolygonOnTriangulation (aUMaxIso);
|
||||
Handle(Poly_PolygonOnTriangulation) aVMinPoly = new Poly_PolygonOnTriangulation (aVMinIso);
|
||||
Handle(Poly_PolygonOnTriangulation) aVMaxPoly = new Poly_PolygonOnTriangulation (aVMaxIso);
|
||||
for (TopExp_Explorer exp (aFace, TopAbs_EDGE); exp.More(); exp.Next())
|
||||
{
|
||||
TopoDS_Edge anEdge = TopoDS::Edge (exp.Current());
|
||||
Standard_Real aFirst, aLast;
|
||||
Handle(Geom2d_Curve) aC = BRep_Tool::CurveOnSurface (anEdge, aFace, aFirst, aLast);
|
||||
gp_Pnt2d aPFirst = aC->Value (aFirst);
|
||||
gp_Pnt2d aPLast = aC->Value (aLast);
|
||||
if (Abs (aPFirst.X() - aPLast.X()) < 0.1 * (aUMax - aUMin)) // U=const
|
||||
{
|
||||
if (BRep_Tool::IsClosed (anEdge, aFace))
|
||||
B.UpdateEdge (anEdge, aUMinPoly, aUMaxPoly, aTriangulation);
|
||||
else
|
||||
B.UpdateEdge (anEdge, (aPFirst.X() < 0.5 * (aUMin + aUMax) ? aUMinPoly : aUMaxPoly), aTriangulation);
|
||||
}
|
||||
else // V=const
|
||||
{
|
||||
if (BRep_Tool::IsClosed (anEdge, aFace))
|
||||
B.UpdateEdge (anEdge, aVMinPoly, aVMaxPoly, aTriangulation);
|
||||
else
|
||||
B.UpdateEdge (anEdge, (aPFirst.Y() < 0.5 * (aVMin + aVMax) ? aVMinPoly : aVMaxPoly), aTriangulation);
|
||||
}
|
||||
}
|
||||
|
||||
DBRep::Set (aResName, aFace);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : MemLeakTest
|
||||
//purpose :
|
||||
@@ -1620,6 +1769,7 @@ void MeshTest::Commands(Draw_Interpretor& theCommands)
|
||||
g = "Mesh Commands";
|
||||
|
||||
theCommands.Add("incmesh","Builds triangular mesh for the shape, run w/o args for help",__FILE__, incrementalmesh, g);
|
||||
theCommands.Add("tessellate","Builds triangular mesh for the surface, run w/o args for help",__FILE__, tessellate, g);
|
||||
theCommands.Add("MemLeakTest","MemLeakTest",__FILE__, MemLeakTest, g);
|
||||
theCommands.Add("fastdiscret","fastdiscret shape deflection",__FILE__, fastdiscret, g);
|
||||
theCommands.Add("mesh","mesh result Shape deflection",__FILE__, triangule, g);
|
||||
|
@@ -366,7 +366,6 @@ static Standard_Integer tricheck (Draw_Interpretor& di, int n, const char ** a)
|
||||
TopLoc_Location aLoc;
|
||||
Handle(Poly_Triangulation) aT = BRep_Tool::Triangulation(aFace, aLoc);
|
||||
const TColgp_Array1OfPnt& aPoints = aT->Nodes();
|
||||
const TColgp_Array1OfPnt2d& aPoints2d = aT->UVNodes();
|
||||
const gp_Trsf& trsf = aLoc.Transformation();
|
||||
|
||||
TColgp_Array1OfPnt pnts(1,2);
|
||||
@@ -381,12 +380,16 @@ static Standard_Integer tricheck (Draw_Interpretor& di, int n, const char ** a)
|
||||
DrawTrSurf::Set (name, poly);
|
||||
DrawTrSurf::Set (name, pnts(1));
|
||||
DrawTrSurf::Set (name, pnts(2));
|
||||
pnts2d(1) = aPoints2d(n1);
|
||||
pnts2d(2) = aPoints2d(n2);
|
||||
Handle(Poly_Polygon2D) poly2d = new Poly_Polygon2D (pnts2d);
|
||||
DrawTrSurf::Set (name, poly2d);
|
||||
DrawTrSurf::Set (name, pnts2d(1));
|
||||
DrawTrSurf::Set (name, pnts2d(2));
|
||||
if (aT->HasUVNodes())
|
||||
{
|
||||
const TColgp_Array1OfPnt2d& aPoints2d = aT->UVNodes();
|
||||
pnts2d(1) = aPoints2d(n1);
|
||||
pnts2d(2) = aPoints2d(n2);
|
||||
Handle(Poly_Polygon2D) poly2d = new Poly_Polygon2D (pnts2d);
|
||||
DrawTrSurf::Set (name, poly2d);
|
||||
DrawTrSurf::Set (name, pnts2d(1));
|
||||
DrawTrSurf::Set (name, pnts2d(2));
|
||||
}
|
||||
}
|
||||
di << "\n";
|
||||
}
|
||||
@@ -428,10 +431,12 @@ static Standard_Integer tricheck (Draw_Interpretor& di, int n, const char ** a)
|
||||
TopLoc_Location aLoc;
|
||||
Handle(Poly_Triangulation) aT = BRep_Tool::Triangulation(aFace, aLoc);
|
||||
const TColgp_Array1OfPnt& aPoints = aT->Nodes();
|
||||
const TColgp_Array1OfPnt2d& aPoints2d = aT->UVNodes();
|
||||
const gp_Trsf& trsf = aLoc.Transformation();
|
||||
DrawTrSurf::Set (name, aPoints(inode).Transformed(trsf));
|
||||
DrawTrSurf::Set (name, aPoints2d(inode));
|
||||
if (aT->HasUVNodes())
|
||||
{
|
||||
DrawTrSurf::Set (name, aT->UVNodes()(inode));
|
||||
}
|
||||
|
||||
di << "{" << iface << " " << inode << "} ";
|
||||
}
|
||||
@@ -520,7 +525,6 @@ static Standard_Integer tricheck (Draw_Interpretor& di, int n, const char ** a)
|
||||
di << "Not connected mesh inside face " << aFaceId << "\n";
|
||||
|
||||
const TColgp_Array1OfPnt& aPoints = aT->Nodes();
|
||||
const TColgp_Array1OfPnt2d& aPoints2d = aT->UVNodes();
|
||||
const gp_Trsf& trsf = aLoc.Transformation();
|
||||
|
||||
TColgp_Array1OfPnt pnts(1,2);
|
||||
@@ -536,12 +540,16 @@ static Standard_Integer tricheck (Draw_Interpretor& di, int n, const char ** a)
|
||||
DrawTrSurf::Set (name, poly);
|
||||
DrawTrSurf::Set (name, pnts(1));
|
||||
DrawTrSurf::Set (name, pnts(2));
|
||||
pnts2d(1) = aPoints2d(aLink.FirstNode());
|
||||
pnts2d(2) = aPoints2d(aLink.LastNode());
|
||||
Handle(Poly_Polygon2D) poly2d = new Poly_Polygon2D (pnts2d);
|
||||
DrawTrSurf::Set (name, poly2d);
|
||||
DrawTrSurf::Set (name, pnts2d(1));
|
||||
DrawTrSurf::Set (name, pnts2d(2));
|
||||
if (aT->HasUVNodes())
|
||||
{
|
||||
const TColgp_Array1OfPnt2d& aPoints2d = aT->UVNodes();
|
||||
pnts2d(1) = aPoints2d(aLink.FirstNode());
|
||||
pnts2d(2) = aPoints2d(aLink.LastNode());
|
||||
Handle(Poly_Polygon2D) poly2d = new Poly_Polygon2D (pnts2d);
|
||||
DrawTrSurf::Set (name, poly2d);
|
||||
DrawTrSurf::Set (name, pnts2d(1));
|
||||
DrawTrSurf::Set (name, pnts2d(2));
|
||||
}
|
||||
}
|
||||
di << "\n";
|
||||
}
|
||||
|
Reference in New Issue
Block a user