mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f50111ec50 |
@@ -454,7 +454,6 @@ t TKRWMesh
|
|||||||
n RWGltf
|
n RWGltf
|
||||||
n RWMesh
|
n RWMesh
|
||||||
n RWObj
|
n RWObj
|
||||||
n RWPly
|
|
||||||
n DFBrowser
|
n DFBrowser
|
||||||
n DFBrowserPane
|
n DFBrowserPane
|
||||||
n DFBrowserPaneXDE
|
n DFBrowserPaneXDE
|
||||||
|
@@ -1,307 +0,0 @@
|
|||||||
// Copyright (c) 2021 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 <BRepLib_PointCloudShape.hxx>
|
|
||||||
|
|
||||||
#include <BRep_Tool.hxx>
|
|
||||||
#include <BRepGProp.hxx>
|
|
||||||
#include <BRepLib_ToolTriangulatedShape.hxx>
|
|
||||||
#include <BRepTools.hxx>
|
|
||||||
#include <BRepTopAdaptor_FClass2d.hxx>
|
|
||||||
#include <Geom_Surface.hxx>
|
|
||||||
#include <GProp_GProps.hxx>
|
|
||||||
#include <gp_Pnt.hxx>
|
|
||||||
#include <gp_Vec.hxx>
|
|
||||||
#include <Precision.hxx>
|
|
||||||
#include <TopExp_Explorer.hxx>
|
|
||||||
#include <TopoDS.hxx>
|
|
||||||
#include <TopoDS_Face.hxx>
|
|
||||||
#include <TopoDS_Shape.hxx>
|
|
||||||
|
|
||||||
#include <random>
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : BRepLib_PointCloudShape
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
BRepLib_PointCloudShape::BRepLib_PointCloudShape (const TopoDS_Shape& theShape,
|
|
||||||
const Standard_Real theTol)
|
|
||||||
: myShape (theShape),
|
|
||||||
myDist (0.0),
|
|
||||||
myTol (theTol),
|
|
||||||
myNbPoints (0)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : ~BRepLib_PointCloudShape
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
BRepLib_PointCloudShape::~BRepLib_PointCloudShape()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : NbPointsByDensity
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
Standard_Integer BRepLib_PointCloudShape::NbPointsByDensity (const Standard_Real theDensity)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
Standard_Real aDensity = (theDensity < Precision::Confusion() ? computeDensity() : theDensity);
|
|
||||||
if (aDensity < Precision::Confusion())
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Integer aNbPoints = 0;
|
|
||||||
for (TopExp_Explorer aExpF(myShape, TopAbs_FACE); aExpF.More(); aExpF.Next())
|
|
||||||
{
|
|
||||||
Standard_Real anArea = faceArea(aExpF.Current());
|
|
||||||
|
|
||||||
Standard_Integer aNbPnts = Max ((Standard_Integer)std::ceil(anArea / theDensity), 1);
|
|
||||||
myFacePoints.Bind(aExpF.Current(), aNbPnts);
|
|
||||||
aNbPoints+= aNbPnts;
|
|
||||||
}
|
|
||||||
return aNbPoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : GeneratePointsByDensity
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
Standard_Boolean BRepLib_PointCloudShape::GeneratePointsByDensity (const Standard_Real theDensity)
|
|
||||||
{
|
|
||||||
if (myFacePoints.IsEmpty())
|
|
||||||
{
|
|
||||||
if (NbPointsByDensity (theDensity) == 0)
|
|
||||||
{
|
|
||||||
return Standard_False;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Integer aNbAdded = 0;
|
|
||||||
for (TopExp_Explorer aExpF (myShape, TopAbs_FACE); aExpF.More(); aExpF.Next())
|
|
||||||
{
|
|
||||||
if (addDensityPoints (aExpF.Current()))
|
|
||||||
{
|
|
||||||
aNbAdded++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (aNbAdded > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : GeneratePointsByTriangulation
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
Standard_Boolean BRepLib_PointCloudShape::GeneratePointsByTriangulation()
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
|
|
||||||
Standard_Integer aNbAdded = 0;
|
|
||||||
for (TopExp_Explorer aExpF (myShape, TopAbs_FACE); aExpF.More(); aExpF.Next())
|
|
||||||
{
|
|
||||||
if (addTriangulationPoints (aExpF.Current()))
|
|
||||||
{
|
|
||||||
aNbAdded++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (aNbAdded > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : faceArea
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
Standard_Real BRepLib_PointCloudShape::faceArea (const TopoDS_Shape& theShape)
|
|
||||||
{
|
|
||||||
Standard_Real anArea = 0.0;
|
|
||||||
if (myFaceArea.Find (theShape, anArea))
|
|
||||||
{
|
|
||||||
return anArea;
|
|
||||||
}
|
|
||||||
|
|
||||||
GProp_GProps aFaceProps;
|
|
||||||
BRepGProp::SurfaceProperties (theShape, aFaceProps);
|
|
||||||
anArea = aFaceProps.Mass();
|
|
||||||
myFaceArea.Bind (theShape, anArea);
|
|
||||||
return anArea;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : computeDensity
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
Standard_Real BRepLib_PointCloudShape::computeDensity()
|
|
||||||
{
|
|
||||||
// at first step find the face with smallest area
|
|
||||||
Standard_Real anAreaMin = Precision::Infinite();
|
|
||||||
for (TopExp_Explorer aExpF (myShape, TopAbs_FACE); aExpF.More(); aExpF.Next())
|
|
||||||
{
|
|
||||||
Standard_Real anArea = faceArea (aExpF.Current());
|
|
||||||
if (anArea < myTol * myTol)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (anArea < anAreaMin)
|
|
||||||
{
|
|
||||||
anAreaMin = anArea;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return anAreaMin * 0.1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : NbPointsByTriangulation
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
Standard_Integer BRepLib_PointCloudShape::NbPointsByTriangulation() const
|
|
||||||
{
|
|
||||||
// at first step find the face with smallest area
|
|
||||||
Standard_Integer aNbPoints = 0;
|
|
||||||
for (TopExp_Explorer aExpF (myShape, TopAbs_FACE); aExpF.More(); aExpF.Next())
|
|
||||||
{
|
|
||||||
TopLoc_Location aLoc;
|
|
||||||
Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (TopoDS::Face (aExpF.Current()), aLoc);
|
|
||||||
if (aTriangulation.IsNull())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
aNbPoints += aTriangulation->NbNodes();
|
|
||||||
}
|
|
||||||
return aNbPoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : addDensityPoints
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
Standard_Boolean BRepLib_PointCloudShape::addDensityPoints (const TopoDS_Shape& theFace)
|
|
||||||
{
|
|
||||||
//addition of the points with specified density on the face by random way
|
|
||||||
Standard_Integer aNbPnts = (myFacePoints.IsBound (theFace) ? myFacePoints.Find (theFace) : 0);
|
|
||||||
if (aNbPnts == 0)
|
|
||||||
{
|
|
||||||
return Standard_False;
|
|
||||||
}
|
|
||||||
|
|
||||||
TopoDS_Face aFace = TopoDS::Face (theFace);
|
|
||||||
Standard_Real anUMin = 0.0, anUMax = 0.0, aVMin = 0.0, aVMax = 0.0;
|
|
||||||
BRepTools::UVBounds (aFace, anUMin, anUMax, aVMin, aVMax);
|
|
||||||
BRepTopAdaptor_FClass2d aClassifier (aFace, Precision::Confusion());
|
|
||||||
|
|
||||||
TopLoc_Location aLoc = theFace.Location();
|
|
||||||
const gp_Trsf& aTrsf = aLoc.Transformation();
|
|
||||||
TopLoc_Location aLoc1;
|
|
||||||
Handle(Geom_Surface) aSurf = BRep_Tool::Surface (aFace, aLoc1);
|
|
||||||
if (aSurf.IsNull())
|
|
||||||
{
|
|
||||||
return Standard_False;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::mt19937 aRandomGenerator(0);
|
|
||||||
std::uniform_real_distribution<> anUDistrib(anUMin, anUMax);
|
|
||||||
std::uniform_real_distribution<> aVDistrib (aVMin, aVMax);
|
|
||||||
for (Standard_Integer nbCurPnts = 1; nbCurPnts <= aNbPnts;)
|
|
||||||
{
|
|
||||||
const Standard_Real aU = anUDistrib(aRandomGenerator);
|
|
||||||
const Standard_Real aV = aVDistrib (aRandomGenerator);
|
|
||||||
gp_Pnt2d aUVNode (aU, aV);
|
|
||||||
const TopAbs_State aState = aClassifier.Perform (aUVNode);
|
|
||||||
if (aState == TopAbs_OUT)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
nbCurPnts++;
|
|
||||||
|
|
||||||
gp_Pnt aP1;
|
|
||||||
gp_Vec dU, dV;
|
|
||||||
aSurf->D1 (aU, aV, aP1, dU, dV);
|
|
||||||
|
|
||||||
gp_Vec aNorm = dU ^ dV;
|
|
||||||
if (aFace.Orientation() == TopAbs_REVERSED)
|
|
||||||
{
|
|
||||||
aNorm.Reverse();
|
|
||||||
}
|
|
||||||
const Standard_Real aNormMod = aNorm.Magnitude();
|
|
||||||
if (aNormMod > gp::Resolution())
|
|
||||||
{
|
|
||||||
aNorm /= aNormMod;
|
|
||||||
}
|
|
||||||
if (myDist > Precision::Confusion())
|
|
||||||
{
|
|
||||||
std::uniform_real_distribution<> aDistanceDistrib (0.0, myDist);
|
|
||||||
gp_XYZ aDeflPoint = aP1.XYZ() + aNorm.XYZ() * aDistanceDistrib (aRandomGenerator);
|
|
||||||
aP1.SetXYZ (aDeflPoint);
|
|
||||||
}
|
|
||||||
aP1.Transform (aTrsf);
|
|
||||||
if (aNormMod > gp::Resolution())
|
|
||||||
{
|
|
||||||
aNorm = gp_Dir (aNorm).Transformed (aTrsf);
|
|
||||||
}
|
|
||||||
addPoint (aP1, aNorm, aUVNode, aFace);
|
|
||||||
}
|
|
||||||
return Standard_True;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : addTriangulationPoints
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
Standard_Boolean BRepLib_PointCloudShape::addTriangulationPoints (const TopoDS_Shape& theFace)
|
|
||||||
{
|
|
||||||
TopLoc_Location aLoc;
|
|
||||||
TopoDS_Face aFace = TopoDS::Face (theFace);
|
|
||||||
Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aLoc);
|
|
||||||
if (aTriangulation.IsNull())
|
|
||||||
{
|
|
||||||
return Standard_False;
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLoc_Location aLoc1;
|
|
||||||
Handle(Geom_Surface) aSurf = BRep_Tool::Surface (aFace, aLoc1);
|
|
||||||
const gp_Trsf& aTrsf = aLoc.Transformation();
|
|
||||||
|
|
||||||
BRepLib_ToolTriangulatedShape::ComputeNormals (aFace, aTriangulation);
|
|
||||||
Standard_Boolean aHasUVNode = aTriangulation->HasUVNodes();
|
|
||||||
for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter)
|
|
||||||
{
|
|
||||||
gp_Pnt aP1 = aTriangulation->Node (aNodeIter);
|
|
||||||
gp_Dir aNormal = aTriangulation->Normal(aNodeIter);
|
|
||||||
if (!aLoc.IsIdentity())
|
|
||||||
{
|
|
||||||
aP1 .Transform (aTrsf);
|
|
||||||
aNormal.Transform (aTrsf);
|
|
||||||
}
|
|
||||||
|
|
||||||
const gp_Pnt2d anUVNode = aHasUVNode ? aTriangulation->UVNode (aNodeIter) : gp_Pnt2d();
|
|
||||||
addPoint (aP1, aNormal, anUVNode, aFace);
|
|
||||||
}
|
|
||||||
return Standard_True;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : clear
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
void BRepLib_PointCloudShape::clear()
|
|
||||||
{
|
|
||||||
myFaceArea.Clear();
|
|
||||||
myFacePoints.Clear();
|
|
||||||
}
|
|
@@ -1,116 +0,0 @@
|
|||||||
// Copyright (c) 2021 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 _BRepLib_PointCloudShape_HeaderFile
|
|
||||||
#define _BRepLib_PointCloudShape_HeaderFile
|
|
||||||
|
|
||||||
#include <TopTools_DataMapOfShapeInteger.hxx>
|
|
||||||
#include <TopTools_DataMapOfShapeReal.hxx>
|
|
||||||
#include <Quantity_Color.hxx>
|
|
||||||
#include <Precision.hxx>
|
|
||||||
|
|
||||||
//! This tool is intended to get points from shape with specified distance from shape along normal.
|
|
||||||
//! Can be used to simulation of points obtained in result of laser scan of shape.
|
|
||||||
//! There are 2 ways for generation points by shape:
|
|
||||||
//! 1. Generation points with specified density
|
|
||||||
//! 2. Generation points using triangulation Nodes
|
|
||||||
//! Generation of points by density using the GeneratePointsByDensity() function is not thread safe.
|
|
||||||
class BRepLib_PointCloudShape
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
DEFINE_STANDARD_ALLOC
|
|
||||||
|
|
||||||
//! Constructor initialized by shape
|
|
||||||
Standard_EXPORT BRepLib_PointCloudShape (const TopoDS_Shape& theShape = TopoDS_Shape(),
|
|
||||||
const Standard_Real theTol = Precision::Confusion());
|
|
||||||
|
|
||||||
//! Virtual destructor
|
|
||||||
Standard_EXPORT virtual ~BRepLib_PointCloudShape();
|
|
||||||
|
|
||||||
//! Return loaded shape.
|
|
||||||
const TopoDS_Shape& Shape() const { return myShape; }
|
|
||||||
|
|
||||||
//! Set shape.
|
|
||||||
void SetShape (const TopoDS_Shape& theShape) { myShape = theShape; }
|
|
||||||
|
|
||||||
//! Return tolerance.
|
|
||||||
Standard_Real Tolerance() const { return myTol; }
|
|
||||||
|
|
||||||
//! Set tolerance.
|
|
||||||
void SetTolerance (Standard_Real theTol) { myTol = theTol; }
|
|
||||||
|
|
||||||
//! Returns value of the distance to define deflection of points from shape along normal to shape; 0.0 by default.
|
|
||||||
Standard_Real GetDistance() const { return myDist; }
|
|
||||||
|
|
||||||
//! Sets value of the distance to define deflection of points from shape along normal to shape.
|
|
||||||
//! Negative values of theDist parameter are ignored.
|
|
||||||
void SetDistance (const Standard_Real theDist) { myDist = theDist; }
|
|
||||||
|
|
||||||
//! Returns size of the point cloud for specified density.
|
|
||||||
Standard_EXPORT Standard_Integer NbPointsByDensity (const Standard_Real theDensity = 0.0);
|
|
||||||
|
|
||||||
//! Returns size of the point cloud for using triangulation.
|
|
||||||
Standard_EXPORT Standard_Integer NbPointsByTriangulation() const;
|
|
||||||
|
|
||||||
//! Computes points with specified density for initial shape.
|
|
||||||
//! If parameter Density is equal to 0 then density will be computed automatically by criterion:
|
|
||||||
//! - 10 points per minimal unreduced face area.
|
|
||||||
//!
|
|
||||||
//! Note: this function should not be called from concurrent threads without external lock.
|
|
||||||
Standard_EXPORT Standard_Boolean GeneratePointsByDensity (const Standard_Real theDensity = 0.0);
|
|
||||||
|
|
||||||
//! Get points from triangulation existing in the shape.
|
|
||||||
Standard_EXPORT Standard_Boolean GeneratePointsByTriangulation();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//! Compute area of the specified face.
|
|
||||||
Standard_EXPORT Standard_Real faceArea (const TopoDS_Shape& theShape);
|
|
||||||
|
|
||||||
//! Computes default density points per face.
|
|
||||||
Standard_EXPORT Standard_Real computeDensity();
|
|
||||||
|
|
||||||
//! Adds points to face in accordance with the specified density randomly in the specified range [0, Dist].
|
|
||||||
Standard_EXPORT Standard_Boolean addDensityPoints (const TopoDS_Shape& theFace);
|
|
||||||
|
|
||||||
//! Adds points to face by nodes of the existing triangulation randomly in the specified range [0, Dist].
|
|
||||||
Standard_EXPORT Standard_Boolean addTriangulationPoints (const TopoDS_Shape& theFace);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//! Method to clear maps.
|
|
||||||
Standard_EXPORT virtual void clear();
|
|
||||||
|
|
||||||
//! Method to add point, normal to surface in this point and face for which point computed.
|
|
||||||
//! @param[in] thePoint 3D point on the surface
|
|
||||||
//! @param[in] theNorm surface normal at this point
|
|
||||||
//! @param[in] theUV surface UV parameters
|
|
||||||
//! @param[in] theFace surface (face) definition
|
|
||||||
Standard_EXPORT virtual void addPoint (const gp_Pnt& thePoint,
|
|
||||||
const gp_Vec& theNorm,
|
|
||||||
const gp_Pnt2d& theUV,
|
|
||||||
const TopoDS_Shape& theFace) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
TopoDS_Shape myShape;
|
|
||||||
Standard_Real myDist;
|
|
||||||
Standard_Real myTol;
|
|
||||||
TopTools_DataMapOfShapeReal myFaceArea;
|
|
||||||
TopTools_DataMapOfShapeInteger myFacePoints;
|
|
||||||
Standard_Integer myNbPoints;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _BRepLib_PointCloudShape_HeaderFile
|
|
@@ -1,83 +0,0 @@
|
|||||||
// Copyright (c) 2021 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 <BRepLib_ToolTriangulatedShape.hxx>
|
|
||||||
|
|
||||||
#include <BRep_Tool.hxx>
|
|
||||||
#include <GeomLib.hxx>
|
|
||||||
#include <Poly.hxx>
|
|
||||||
#include <Poly_Connect.hxx>
|
|
||||||
#include <Precision.hxx>
|
|
||||||
#include <TopLoc_Location.hxx>
|
|
||||||
#include <TopoDS.hxx>
|
|
||||||
#include <TopoDS_Face.hxx>
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : ComputeNormals
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
void BRepLib_ToolTriangulatedShape::ComputeNormals (const TopoDS_Face& theFace,
|
|
||||||
const Handle(Poly_Triangulation)& theTris,
|
|
||||||
Poly_Connect& thePolyConnect)
|
|
||||||
{
|
|
||||||
if (theTris.IsNull()
|
|
||||||
|| theTris->HasNormals())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// take in face the surface location
|
|
||||||
const TopoDS_Face aZeroFace = TopoDS::Face (theFace.Located (TopLoc_Location()));
|
|
||||||
Handle(Geom_Surface) aSurf = BRep_Tool::Surface (aZeroFace);
|
|
||||||
if (!theTris->HasUVNodes() || aSurf.IsNull())
|
|
||||||
{
|
|
||||||
// compute normals by averaging triangulation normals sharing the same vertex
|
|
||||||
Poly::ComputeNormals (theTris);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Standard_Real aTol = Precision::Confusion();
|
|
||||||
Standard_Integer aTri[3];
|
|
||||||
gp_Dir aNorm;
|
|
||||||
theTris->AddNormals();
|
|
||||||
for (Standard_Integer aNodeIter = 1; aNodeIter <= theTris->NbNodes(); ++aNodeIter)
|
|
||||||
{
|
|
||||||
// try to retrieve normal from real surface first, when UV coordinates are available
|
|
||||||
if (GeomLib::NormEstim (aSurf, theTris->UVNode (aNodeIter), aTol, aNorm) > 1)
|
|
||||||
{
|
|
||||||
if (thePolyConnect.Triangulation() != theTris)
|
|
||||||
{
|
|
||||||
thePolyConnect.Load (theTris);
|
|
||||||
}
|
|
||||||
|
|
||||||
// compute flat normals
|
|
||||||
gp_XYZ eqPlan (0.0, 0.0, 0.0);
|
|
||||||
for (thePolyConnect.Initialize (aNodeIter); thePolyConnect.More(); thePolyConnect.Next())
|
|
||||||
{
|
|
||||||
theTris->Triangle (thePolyConnect.Value()).Get (aTri[0], aTri[1], aTri[2]);
|
|
||||||
const gp_XYZ v1 (theTris->Node (aTri[1]).Coord() - theTris->Node (aTri[0]).Coord());
|
|
||||||
const gp_XYZ v2 (theTris->Node (aTri[2]).Coord() - theTris->Node (aTri[1]).Coord());
|
|
||||||
const gp_XYZ vv = v1 ^ v2;
|
|
||||||
const Standard_Real aMod = vv.Modulus();
|
|
||||||
if (aMod >= aTol)
|
|
||||||
{
|
|
||||||
eqPlan += vv / aMod;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const Standard_Real aModMax = eqPlan.Modulus();
|
|
||||||
aNorm = (aModMax > aTol) ? gp_Dir (eqPlan) : gp::DZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
theTris->SetNormal (aNodeIter, aNorm);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,50 +0,0 @@
|
|||||||
// Copyright (c) 2021 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 _BrepLib_ToolTriangulatedShape_HeaderFile
|
|
||||||
#define _BrepLib_ToolTriangulatedShape_HeaderFile
|
|
||||||
|
|
||||||
#include <Poly_Connect.hxx>
|
|
||||||
#include <Poly_Triangulation.hxx>
|
|
||||||
|
|
||||||
class TopoDS_Face;
|
|
||||||
class Poly_Triangulation;
|
|
||||||
|
|
||||||
//! Provides methods for calculating normals to Poly_Triangulation of TopoDS_Face.
|
|
||||||
class BRepLib_ToolTriangulatedShape
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! Computes nodal normals for Poly_Triangulation structure using UV coordinates and surface.
|
|
||||||
//! Does nothing if triangulation already defines normals.
|
|
||||||
//! @param[in] theFace the face
|
|
||||||
//! @param[in] theTris the definition of a face triangulation
|
|
||||||
static void ComputeNormals (const TopoDS_Face& theFace,
|
|
||||||
const Handle(Poly_Triangulation)& theTris)
|
|
||||||
{
|
|
||||||
Poly_Connect aPolyConnect;
|
|
||||||
ComputeNormals (theFace, theTris, aPolyConnect);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Computes nodal normals for Poly_Triangulation structure using UV coordinates and surface.
|
|
||||||
//! Does nothing if triangulation already defines normals.
|
|
||||||
//! @param[in] theFace the face
|
|
||||||
//! @param[in] theTris the definition of a face triangulation
|
|
||||||
//! @param[in,out] thePolyConnect optional, initialized tool for exploring triangulation
|
|
||||||
Standard_EXPORT static void ComputeNormals (const TopoDS_Face& theFace,
|
|
||||||
const Handle(Poly_Triangulation)& theTris,
|
|
||||||
Poly_Connect& thePolyConnect);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@@ -30,12 +30,8 @@ BRepLib_MakeVertex.hxx
|
|||||||
BRepLib_MakeWire.cxx
|
BRepLib_MakeWire.cxx
|
||||||
BRepLib_MakeWire.hxx
|
BRepLib_MakeWire.hxx
|
||||||
BRepLib_MakeWire_1.cxx
|
BRepLib_MakeWire_1.cxx
|
||||||
BRepLib_PointCloudShape.hxx
|
|
||||||
BRepLib_PointCloudShape.cxx
|
|
||||||
BRepLib_ShapeModification.hxx
|
BRepLib_ShapeModification.hxx
|
||||||
BRepLib_ShellError.hxx
|
BRepLib_ShellError.hxx
|
||||||
BRepLib_ToolTriangulatedShape.hxx
|
|
||||||
BRepLib_ToolTriangulatedShape.cxx
|
|
||||||
BRepLib_ValidateEdge.cxx
|
BRepLib_ValidateEdge.cxx
|
||||||
BRepLib_ValidateEdge.hxx
|
BRepLib_ValidateEdge.hxx
|
||||||
BRepLib_WireError.hxx
|
BRepLib_WireError.hxx
|
||||||
|
@@ -48,8 +48,7 @@ BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh( const TopoDS_Shape& theSh
|
|||||||
const Standard_Real theLinDeflection,
|
const Standard_Real theLinDeflection,
|
||||||
const Standard_Boolean isRelative,
|
const Standard_Boolean isRelative,
|
||||||
const Standard_Real theAngDeflection,
|
const Standard_Real theAngDeflection,
|
||||||
const Standard_Boolean isInParallel,
|
const Standard_Boolean isInParallel)
|
||||||
const Message_ProgressRange& theRange)
|
|
||||||
: myModified(Standard_False),
|
: myModified(Standard_False),
|
||||||
myStatus(IMeshData_NoError)
|
myStatus(IMeshData_NoError)
|
||||||
{
|
{
|
||||||
@@ -59,7 +58,7 @@ BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh( const TopoDS_Shape& theSh
|
|||||||
myParameters.InParallel = isInParallel;
|
myParameters.InParallel = isInParallel;
|
||||||
|
|
||||||
myShape = theShape;
|
myShape = theShape;
|
||||||
Perform(theRange);
|
Perform();
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
@@ -43,8 +43,7 @@ public: //! @name mesher API
|
|||||||
const Standard_Real theLinDeflection,
|
const Standard_Real theLinDeflection,
|
||||||
const Standard_Boolean isRelative = Standard_False,
|
const Standard_Boolean isRelative = Standard_False,
|
||||||
const Standard_Real theAngDeflection = 0.5,
|
const Standard_Real theAngDeflection = 0.5,
|
||||||
const Standard_Boolean isInParallel = Standard_False,
|
const Standard_Boolean isInParallel = Standard_False);
|
||||||
const Message_ProgressRange& theRange = Message_ProgressRange());
|
|
||||||
|
|
||||||
//! Constructor.
|
//! Constructor.
|
||||||
//! Automatically calls method Perform.
|
//! Automatically calls method Perform.
|
||||||
|
@@ -133,7 +133,7 @@ namespace
|
|||||||
{
|
{
|
||||||
if (aDEdge->GetCurve()->ParametersNb() == 2)
|
if (aDEdge->GetCurve()->ParametersNb() == 2)
|
||||||
{
|
{
|
||||||
if (splitEdge (aDEdge, aDFace, Abs (getConeStep (aDFace))))
|
if (splitEdge (aDEdge, Abs (getConeStep (aDFace))))
|
||||||
{
|
{
|
||||||
TopLoc_Location aLoc;
|
TopLoc_Location aLoc;
|
||||||
const Handle (Poly_Triangulation)& aTriangulation =
|
const Handle (Poly_Triangulation)& aTriangulation =
|
||||||
@@ -178,89 +178,48 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Splits 3D and all pcurves accordingly using the specified step.
|
//! Splits 3D and all pcurves accordingly using the specified step.
|
||||||
Standard_Boolean splitEdge(const IMeshData::IEdgePtr& theDEdge,
|
Standard_Boolean splitEdge(const IMeshData::IEdgePtr& theDEdge,
|
||||||
const IMeshData::IFaceHandle& theDFace,
|
const Standard_Real theDU) const
|
||||||
const Standard_Real theDU) const
|
|
||||||
{
|
{
|
||||||
TopoDS_Edge aE = theDEdge->GetEdge();
|
if (!splitCurve<gp_XYZ> (theDEdge->GetCurve (), theDU))
|
||||||
const TopoDS_Face& aF = theDFace->GetFace();
|
|
||||||
|
|
||||||
Standard_Real aFParam, aLParam;
|
|
||||||
|
|
||||||
Handle(Geom_Curve) aHC = BRep_Tool::Curve (aE, aFParam, aLParam);
|
|
||||||
|
|
||||||
const IMeshData::IPCurveHandle& aIPC1 = theDEdge->GetPCurve(0);
|
|
||||||
const IMeshData::IPCurveHandle& aIPC2 = theDEdge->GetPCurve(1);
|
|
||||||
|
|
||||||
// Calculate the step by parameter of the curve.
|
|
||||||
const gp_Pnt2d& aFPntOfIPC1 = aIPC1->GetPoint (0);
|
|
||||||
const gp_Pnt2d& aLPntOfIPC1 = aIPC1->GetPoint (aIPC1->ParametersNb() - 1);
|
|
||||||
const Standard_Real aMod = Abs (aFPntOfIPC1.Y() - aLPntOfIPC1.Y());
|
|
||||||
|
|
||||||
if (aMod < gp::Resolution())
|
|
||||||
{
|
{
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Standard_Real aDT = Abs (aLParam - aFParam) / aMod * theDU;
|
for (Standard_Integer aPCurveIdx = 0; aPCurveIdx < theDEdge->PCurvesNb(); ++aPCurveIdx)
|
||||||
|
|
||||||
if (!splitCurve<gp_Pnt> (aHC, theDEdge->GetCurve(), aDT))
|
|
||||||
{
|
{
|
||||||
return Standard_False;
|
splitCurve<gp_XY> (theDEdge->GetPCurve (aPCurveIdx), theDU);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define two pcurves of the seam-edge.
|
|
||||||
Handle(Geom2d_Curve) aPC1, aPC2;
|
|
||||||
Standard_Real af, al;
|
|
||||||
|
|
||||||
aE.Orientation (TopAbs_FORWARD);
|
|
||||||
aPC1 = BRep_Tool::CurveOnSurface (aE, aF, af, al);
|
|
||||||
|
|
||||||
aE.Orientation (TopAbs_REVERSED);
|
|
||||||
aPC2 = BRep_Tool::CurveOnSurface (aE, aF, af, al);
|
|
||||||
|
|
||||||
if (aPC1.IsNull() || aPC2.IsNull())
|
|
||||||
{
|
|
||||||
return Standard_False;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select the correct pcurve of the seam-edge.
|
|
||||||
const gp_Pnt2d& aFPntOfPC1 = aPC1->Value (aPC1->FirstParameter());
|
|
||||||
|
|
||||||
if (Abs (aLPntOfIPC1.X() - aFPntOfPC1.X()) > Precision::Confusion())
|
|
||||||
{
|
|
||||||
std::swap (aPC1, aPC2);
|
|
||||||
}
|
|
||||||
|
|
||||||
splitCurve<gp_Pnt2d> (aPC1, aIPC1, aDT);
|
|
||||||
splitCurve<gp_Pnt2d> (aPC2, aIPC2, aDT);
|
|
||||||
|
|
||||||
return Standard_True;
|
return Standard_True;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Splits the given curve using the specified step.
|
//! Splits the given curve using the specified step.
|
||||||
template<class PointType, class GeomCurve, class Curve>
|
template<class PointType, class Curve>
|
||||||
Standard_Boolean splitCurve(GeomCurve& theGeomCurve,
|
Standard_Boolean splitCurve(Curve& theCurve, const Standard_Real theDU) const
|
||||||
Curve& theCurve,
|
|
||||||
const Standard_Real theDT) const
|
|
||||||
{
|
{
|
||||||
Standard_Boolean isUpdated = Standard_False;
|
Standard_Boolean isUpdated = Standard_False;
|
||||||
|
PointType aDir = theCurve->GetPoint(theCurve->ParametersNb() - 1).Coord() - theCurve->GetPoint(0).Coord();
|
||||||
|
const Standard_Real aModulus = aDir.Modulus();
|
||||||
|
if (aModulus < gp::Resolution())
|
||||||
|
{
|
||||||
|
return isUpdated;
|
||||||
|
}
|
||||||
|
aDir /= aModulus;
|
||||||
|
|
||||||
const Standard_Real aFirstParam = theCurve->GetParameter (0);
|
const Standard_Real aLastParam = theCurve->GetParameter(theCurve->ParametersNb() - 1);
|
||||||
const Standard_Real aLastParam = theCurve->GetParameter (theCurve->ParametersNb() - 1);
|
const Standard_Boolean isReversed = theCurve->GetParameter(0) > aLastParam;
|
||||||
const Standard_Boolean isReversed = aFirstParam > aLastParam;
|
|
||||||
|
|
||||||
for (Standard_Integer aPointIdx = 1; ; ++aPointIdx)
|
for (Standard_Integer aPointIdx = 1; ; ++aPointIdx)
|
||||||
{
|
{
|
||||||
const Standard_Real aCurrParam = aFirstParam + aPointIdx * theDT * (isReversed ? -1.0 : 1.0);
|
const Standard_Real aCurrParam = theCurve->GetParameter(0) + aPointIdx * theDU * (isReversed ? -1.0 : 1.0);
|
||||||
if (( isReversed && (aCurrParam - aLastParam < Precision::PConfusion())) ||
|
if (( isReversed && (aCurrParam < aLastParam)) ||
|
||||||
(!isReversed && !(aCurrParam - aLastParam < - Precision::PConfusion())))
|
(!isReversed && !(aCurrParam < aLastParam)))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
theCurve->InsertPoint (theCurve->ParametersNb() - 1,
|
theCurve->InsertPoint(theCurve->ParametersNb() - 1,
|
||||||
theGeomCurve->Value (aCurrParam),
|
theCurve->GetPoint(0).Translated (aDir * aPointIdx * theDU),
|
||||||
aCurrParam);
|
aCurrParam);
|
||||||
|
|
||||||
isUpdated = Standard_True;
|
isUpdated = Standard_True;
|
||||||
|
@@ -26,7 +26,6 @@
|
|||||||
#include <Precision.hxx>
|
#include <Precision.hxx>
|
||||||
#include <Standard_Type.hxx>
|
#include <Standard_Type.hxx>
|
||||||
#include <TDataStd_Integer.hxx>
|
#include <TDataStd_Integer.hxx>
|
||||||
#include <TDataStd_Name.hxx>
|
|
||||||
#include <TDF_Label.hxx>
|
#include <TDF_Label.hxx>
|
||||||
#include <TFunction_Function.hxx>
|
#include <TFunction_Function.hxx>
|
||||||
#include <TFunction_Logbook.hxx>
|
#include <TFunction_Logbook.hxx>
|
||||||
|
@@ -18,7 +18,6 @@
|
|||||||
#include <DrawTrSurf.hxx>
|
#include <DrawTrSurf.hxx>
|
||||||
#include <Message.hxx>
|
#include <Message.hxx>
|
||||||
#include <Message_PrinterOStream.hxx>
|
#include <Message_PrinterOStream.hxx>
|
||||||
#include <Message_PrinterSystemLog.hxx>
|
|
||||||
#include <NCollection_IndexedMap.hxx>
|
#include <NCollection_IndexedMap.hxx>
|
||||||
#include <OSD.hxx>
|
#include <OSD.hxx>
|
||||||
#include <OSD_Thread.hxx>
|
#include <OSD_Thread.hxx>
|
||||||
|
@@ -504,6 +504,7 @@ void IntTools_FaceFace::Perform (const TopoDS_Face& aF1,
|
|||||||
|
|
||||||
{
|
{
|
||||||
const Standard_Real UVMaxStep = IntPatch_Intersection::DefineUVMaxStep(myHS1, dom1, myHS2, dom2);
|
const Standard_Real UVMaxStep = IntPatch_Intersection::DefineUVMaxStep(myHS1, dom1, myHS2, dom2);
|
||||||
|
// TODO: bug32811 Deflection change to 0.01 can work
|
||||||
const Standard_Real Deflection = 0.1;
|
const Standard_Real Deflection = 0.1;
|
||||||
myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection);
|
myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection);
|
||||||
}
|
}
|
||||||
|
@@ -448,5 +448,5 @@ void IntTools_TopolTool::SamplePnts(const Standard_Real theDefl,
|
|||||||
myV0 = myVPars->Value(1);
|
myV0 = myVPars->Value(1);
|
||||||
|
|
||||||
myDU = (myUPars->Value(myNbSmplU) - myU0)/(myNbSmplU-1);
|
myDU = (myUPars->Value(myNbSmplU) - myU0)/(myNbSmplU-1);
|
||||||
myDV = (myVPars->Value(myNbSmplV) - myU0)/(myNbSmplV-1);
|
myDV = (myVPars->Value(myNbSmplV) - myV0)/(myNbSmplV-1);
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +0,0 @@
|
|||||||
RWPly_CafWriter.cxx
|
|
||||||
RWPly_CafWriter.hxx
|
|
||||||
RWPly_PlyWriterContext.cxx
|
|
||||||
RWPly_PlyWriterContext.hxx
|
|
@@ -1,302 +0,0 @@
|
|||||||
// Copyright (c) 2022 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 <RWPly_CafWriter.hxx>
|
|
||||||
|
|
||||||
#include <Message.hxx>
|
|
||||||
#include <Message_LazyProgressScope.hxx>
|
|
||||||
#include <OSD_Path.hxx>
|
|
||||||
#include <RWMesh_FaceIterator.hxx>
|
|
||||||
#include <RWMesh_MaterialMap.hxx>
|
|
||||||
#include <RWPly_PlyWriterContext.hxx>
|
|
||||||
#include <Standard_CLocaleSentry.hxx>
|
|
||||||
#include <TDocStd_Document.hxx>
|
|
||||||
#include <TDataStd_Name.hxx>
|
|
||||||
#include <XCAFDoc_DocumentTool.hxx>
|
|
||||||
#include <XCAFDoc_ShapeTool.hxx>
|
|
||||||
#include <XCAFPrs_DocumentExplorer.hxx>
|
|
||||||
|
|
||||||
IMPLEMENT_STANDARD_RTTIEXT(RWPly_CafWriter, Standard_Transient)
|
|
||||||
|
|
||||||
//================================================================
|
|
||||||
// Function : Constructor
|
|
||||||
// Purpose :
|
|
||||||
//================================================================
|
|
||||||
RWPly_CafWriter::RWPly_CafWriter (const TCollection_AsciiString& theFile)
|
|
||||||
: myFile (theFile),
|
|
||||||
myIsDoublePrec (false),
|
|
||||||
myHasNormals (true),
|
|
||||||
myHasColors (true),
|
|
||||||
myHasTexCoords (false),
|
|
||||||
myHasPartId (true),
|
|
||||||
myHasFaceId (false)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//================================================================
|
|
||||||
// Function : Destructor
|
|
||||||
// Purpose :
|
|
||||||
//================================================================
|
|
||||||
RWPly_CafWriter::~RWPly_CafWriter()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//================================================================
|
|
||||||
// Function : toSkipFaceMesh
|
|
||||||
// Purpose :
|
|
||||||
//================================================================
|
|
||||||
Standard_Boolean RWPly_CafWriter::toSkipFaceMesh (const RWMesh_FaceIterator& theFaceIter)
|
|
||||||
{
|
|
||||||
return theFaceIter.IsEmptyMesh();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : Perform
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
bool RWPly_CafWriter::Perform (const Handle(TDocStd_Document)& theDocument,
|
|
||||||
const TColStd_IndexedDataMapOfStringString& theFileInfo,
|
|
||||||
const Message_ProgressRange& theProgress)
|
|
||||||
{
|
|
||||||
TDF_LabelSequence aRoots;
|
|
||||||
Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (theDocument->Main());
|
|
||||||
aShapeTool->GetFreeShapes (aRoots);
|
|
||||||
return Perform (theDocument, aRoots, NULL, theFileInfo, theProgress);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : Perform
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
bool RWPly_CafWriter::Perform (const Handle(TDocStd_Document)& theDocument,
|
|
||||||
const TDF_LabelSequence& theRootLabels,
|
|
||||||
const TColStd_MapOfAsciiString* theLabelFilter,
|
|
||||||
const TColStd_IndexedDataMapOfStringString& theFileInfo,
|
|
||||||
const Message_ProgressRange& theProgress)
|
|
||||||
{
|
|
||||||
TCollection_AsciiString aFolder, aFileName, aFullFileNameBase, aShortFileNameBase, aFileExt;
|
|
||||||
OSD_Path::FolderAndFileFromPath (myFile, aFolder, aFileName);
|
|
||||||
OSD_Path::FileNameAndExtension (aFileName, aShortFileNameBase, aFileExt);
|
|
||||||
|
|
||||||
Standard_Real aLengthUnit = 1.;
|
|
||||||
if (XCAFDoc_DocumentTool::GetLengthUnit(theDocument, aLengthUnit))
|
|
||||||
{
|
|
||||||
myCSTrsf.SetInputLengthUnit(aLengthUnit);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (theRootLabels.IsEmpty()
|
|
||||||
|| (theLabelFilter != NULL && theLabelFilter->IsEmpty()))
|
|
||||||
{
|
|
||||||
Message::SendFail ("Nothing to export into PLY file");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Integer aNbNodesAll = 0, aNbElemsAll = 0;
|
|
||||||
Standard_Real aNbPEntities = 0; // steps for progress range
|
|
||||||
for (XCAFPrs_DocumentExplorer aDocExplorer (theDocument, theRootLabels, XCAFPrs_DocumentExplorerFlags_OnlyLeafNodes);
|
|
||||||
aDocExplorer.More(); aDocExplorer.Next())
|
|
||||||
{
|
|
||||||
const XCAFPrs_DocumentNode& aDocNode = aDocExplorer.Current();
|
|
||||||
if (theLabelFilter != NULL
|
|
||||||
&& !theLabelFilter->Contains (aDocNode.Id))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (RWMesh_FaceIterator aFaceIter (aDocNode.RefLabel, aDocNode.Location, true, aDocNode.Style); aFaceIter.More(); aFaceIter.Next())
|
|
||||||
{
|
|
||||||
if (toSkipFaceMesh (aFaceIter))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
addFaceInfo (aFaceIter, aNbNodesAll, aNbElemsAll);
|
|
||||||
aNbPEntities += aNbNodesAll + aNbElemsAll;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (aNbNodesAll == 0)
|
|
||||||
{
|
|
||||||
Message::SendFail ("No mesh data to save");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_CLocaleSentry aLocaleSentry;
|
|
||||||
RWPly_PlyWriterContext aPlyCtx;
|
|
||||||
aPlyCtx.SetDoublePrecision (myIsDoublePrec);
|
|
||||||
aPlyCtx.SetNormals (myHasNormals);
|
|
||||||
aPlyCtx.SetColors (myHasColors);
|
|
||||||
aPlyCtx.SetTexCoords (myHasTexCoords);
|
|
||||||
aPlyCtx.SetSurfaceId (myHasPartId || myHasFaceId);
|
|
||||||
if (!aPlyCtx.Open (myFile)
|
|
||||||
|| !aPlyCtx.WriteHeader (aNbNodesAll, aNbElemsAll, theFileInfo))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// simple global progress sentry
|
|
||||||
const Standard_Real aPatchStep = 2048.0;
|
|
||||||
Message_LazyProgressScope aPSentry (theProgress, "PLY export", aNbPEntities, aPatchStep);
|
|
||||||
|
|
||||||
bool isDone = true;
|
|
||||||
for (Standard_Integer aStepIter = 0; aStepIter < 2; ++aStepIter)
|
|
||||||
{
|
|
||||||
aPlyCtx.SetSurfaceId (0);
|
|
||||||
for (XCAFPrs_DocumentExplorer aDocExplorer (theDocument, theRootLabels, XCAFPrs_DocumentExplorerFlags_OnlyLeafNodes);
|
|
||||||
aDocExplorer.More() && !aPSentry.IsAborted(); aDocExplorer.Next())
|
|
||||||
{
|
|
||||||
const XCAFPrs_DocumentNode& aDocNode = aDocExplorer.Current();
|
|
||||||
if (theLabelFilter != NULL
|
|
||||||
&& !theLabelFilter->Contains (aDocNode.Id))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (myHasPartId)
|
|
||||||
{
|
|
||||||
aPlyCtx.SetSurfaceId (aPlyCtx.SurfaceId() + 1);
|
|
||||||
}
|
|
||||||
if (!writeShape (aPlyCtx, aPSentry, aStepIter, aDocNode.RefLabel, aDocNode.Location, aDocNode.Style))
|
|
||||||
{
|
|
||||||
isDone = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool isClosed = aPlyCtx.Close();
|
|
||||||
if (isDone && !isClosed)
|
|
||||||
{
|
|
||||||
Message::SendFail (TCollection_AsciiString ("Failed to write PLY file\n") + myFile);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return isDone && !aPSentry.IsAborted();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : addFaceInfo
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
void RWPly_CafWriter::addFaceInfo (const RWMesh_FaceIterator& theFace,
|
|
||||||
Standard_Integer& theNbNodes,
|
|
||||||
Standard_Integer& theNbElems)
|
|
||||||
{
|
|
||||||
theNbNodes += theFace.NbNodes();
|
|
||||||
theNbElems += theFace.NbTriangles();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : writeShape
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
bool RWPly_CafWriter::writeShape (RWPly_PlyWriterContext& theWriter,
|
|
||||||
Message_LazyProgressScope& thePSentry,
|
|
||||||
const Standard_Integer theWriteStep,
|
|
||||||
const TDF_Label& theLabel,
|
|
||||||
const TopLoc_Location& theParentTrsf,
|
|
||||||
const XCAFPrs_Style& theParentStyle)
|
|
||||||
{
|
|
||||||
for (RWMesh_FaceIterator aFaceIter (theLabel, theParentTrsf, true, theParentStyle); aFaceIter.More() && !thePSentry.IsAborted(); aFaceIter.Next())
|
|
||||||
{
|
|
||||||
if (toSkipFaceMesh (aFaceIter))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (theWriteStep == 0
|
|
||||||
&& !writeNodes (theWriter, thePSentry, aFaceIter))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (theWriteStep == 1
|
|
||||||
&& !writeIndices (theWriter, thePSentry, aFaceIter))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : writeNodes
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
bool RWPly_CafWriter::writeNodes (RWPly_PlyWriterContext& theWriter,
|
|
||||||
Message_LazyProgressScope& thePSentry,
|
|
||||||
const RWMesh_FaceIterator& theFace)
|
|
||||||
{
|
|
||||||
const Standard_Integer aNodeUpper = theFace.NodeUpper();
|
|
||||||
Graphic3d_Vec3 aNormVec;
|
|
||||||
Graphic3d_Vec2 aTexVec;
|
|
||||||
Graphic3d_Vec4ub aColorVec (255);
|
|
||||||
if (theFace.HasFaceColor())
|
|
||||||
{
|
|
||||||
//Graphic3d_Vec4 aColorF = Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB (theFace.FaceColor());
|
|
||||||
Graphic3d_Vec4 aColorF = theFace.FaceColor();
|
|
||||||
aColorVec.SetValues ((unsigned char )int(aColorF.r() * 255.0f),
|
|
||||||
(unsigned char )int(aColorF.g() * 255.0f),
|
|
||||||
(unsigned char )int(aColorF.b() * 255.0f),
|
|
||||||
(unsigned char )int(aColorF.a() * 255.0f));
|
|
||||||
}
|
|
||||||
for (Standard_Integer aNodeIter = theFace.NodeLower(); aNodeIter <= aNodeUpper && thePSentry.More(); ++aNodeIter, thePSentry.Next())
|
|
||||||
{
|
|
||||||
gp_XYZ aNode = theFace.NodeTransformed (aNodeIter).XYZ();
|
|
||||||
myCSTrsf.TransformPosition (aNode);
|
|
||||||
if (theFace.HasNormals())
|
|
||||||
{
|
|
||||||
gp_Dir aNorm = theFace.NormalTransformed (aNodeIter);
|
|
||||||
aNormVec.SetValues ((float )aNorm.X(), (float )aNorm.Y(), (float )aNorm.Z());
|
|
||||||
myCSTrsf.TransformNormal (aNormVec);
|
|
||||||
}
|
|
||||||
if (theFace.HasTexCoords())
|
|
||||||
{
|
|
||||||
const gp_Pnt2d aUV = theFace.NodeTexCoord (aNodeIter);
|
|
||||||
aTexVec.SetValues ((float )aUV.X(), (float )aUV.Y());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!theWriter.WriteVertex (aNode, aNormVec, aTexVec, aColorVec))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : writeIndices
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
bool RWPly_CafWriter::writeIndices (RWPly_PlyWriterContext& theWriter,
|
|
||||||
Message_LazyProgressScope& thePSentry,
|
|
||||||
const RWMesh_FaceIterator& theFace)
|
|
||||||
{
|
|
||||||
if (myHasFaceId)
|
|
||||||
{
|
|
||||||
theWriter.SetSurfaceId (theWriter.SurfaceId() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Standard_Integer anElemLower = theFace.ElemLower();
|
|
||||||
const Standard_Integer anElemUpper = theFace.ElemUpper();
|
|
||||||
for (Standard_Integer anElemIter = anElemLower; anElemIter <= anElemUpper && thePSentry.More(); ++anElemIter, thePSentry.Next())
|
|
||||||
{
|
|
||||||
const Poly_Triangle aTri = theFace.TriangleOriented (anElemIter);
|
|
||||||
if (!theWriter.WriteTriangle (Graphic3d_Vec3i (aTri(1), aTri(2), aTri(3)) - Graphic3d_Vec3i (anElemLower)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
theWriter.SetVertexOffset (theWriter.VertexOffset() + theFace.NbNodes());
|
|
||||||
return true;
|
|
||||||
}
|
|
@@ -1,198 +0,0 @@
|
|||||||
// Copyright (c) 2022 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 _RWPly_CafWriter_HeaderFiler
|
|
||||||
#define _RWPly_CafWriter_HeaderFiler
|
|
||||||
|
|
||||||
#include <TColStd_IndexedDataMapOfStringString.hxx>
|
|
||||||
#include <TColStd_MapOfAsciiString.hxx>
|
|
||||||
#include <TDF_LabelSequence.hxx>
|
|
||||||
#include <TopTools_ShapeMapHasher.hxx>
|
|
||||||
#include <RWMesh_CoordinateSystemConverter.hxx>
|
|
||||||
#include <XCAFPrs_Style.hxx>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
class Message_ProgressRange;
|
|
||||||
class RWMesh_FaceIterator;
|
|
||||||
class TDocStd_Document;
|
|
||||||
|
|
||||||
class Message_LazyProgressScope;
|
|
||||||
class RWPly_PlyWriterContext;
|
|
||||||
|
|
||||||
//! PLY writer context from XCAF document.
|
|
||||||
class RWPly_CafWriter : public Standard_Transient
|
|
||||||
{
|
|
||||||
DEFINE_STANDARD_RTTIEXT(RWPly_CafWriter, Standard_Transient)
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! Main constructor.
|
|
||||||
//! @param[in] theFile path to output PLY file
|
|
||||||
Standard_EXPORT RWPly_CafWriter (const TCollection_AsciiString& theFile);
|
|
||||||
|
|
||||||
//! Destructor.
|
|
||||||
Standard_EXPORT virtual ~RWPly_CafWriter();
|
|
||||||
|
|
||||||
//! Return transformation from OCCT to PLY coordinate system.
|
|
||||||
const RWMesh_CoordinateSystemConverter& CoordinateSystemConverter() const { return myCSTrsf; }
|
|
||||||
|
|
||||||
//! Return transformation from OCCT to PLY coordinate system.
|
|
||||||
RWMesh_CoordinateSystemConverter& ChangeCoordinateSystemConverter() { return myCSTrsf; }
|
|
||||||
|
|
||||||
//! Set transformation from OCCT to PLY coordinate system.
|
|
||||||
void SetCoordinateSystemConverter (const RWMesh_CoordinateSystemConverter& theConverter) { myCSTrsf = theConverter; }
|
|
||||||
|
|
||||||
//! Return default material definition to be used for nodes with only color defined.
|
|
||||||
const XCAFPrs_Style& DefaultStyle() const { return myDefaultStyle; }
|
|
||||||
|
|
||||||
//! Set default material definition to be used for nodes with only color defined.
|
|
||||||
void SetDefaultStyle (const XCAFPrs_Style& theStyle) { myDefaultStyle = theStyle; }
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! Return TRUE if vertex position should be stored with double floating point precision; FALSE by default.
|
|
||||||
bool IsDoublePrecision() const { return myIsDoublePrec; }
|
|
||||||
|
|
||||||
//! Set if vertex position should be stored with double floating point precision.
|
|
||||||
void SetDoublePrecision (bool theDoublePrec) { myIsDoublePrec = theDoublePrec; }
|
|
||||||
|
|
||||||
//! Return TRUE if normals should be written; TRUE by default.
|
|
||||||
bool HasNormals() const { return myHasNormals; }
|
|
||||||
|
|
||||||
//! Set if normals are defined.
|
|
||||||
void SetNormals (const bool theHasNormals) { myHasNormals = theHasNormals; }
|
|
||||||
|
|
||||||
//! Return TRUE if UV / texture coordinates should be written; FALSE by default.
|
|
||||||
bool HasTexCoords() const { return myHasTexCoords; }
|
|
||||||
|
|
||||||
//! Set if UV / texture coordinates should be written.
|
|
||||||
void SetTexCoords (const bool theHasTexCoords) { myHasTexCoords = theHasTexCoords; }
|
|
||||||
|
|
||||||
//! Return TRUE if point colors should be written; TRUE by default.
|
|
||||||
bool HasColors() const { return myHasColors; }
|
|
||||||
|
|
||||||
//! Set if point colors should be written.
|
|
||||||
void SetColors (bool theToWrite) { myHasColors = theToWrite; }
|
|
||||||
|
|
||||||
//! Return TRUE if part Id should be written as element attribute; TRUE by default.
|
|
||||||
bool HasPartId() const { return myHasPartId; }
|
|
||||||
|
|
||||||
//! Set if part Id should be written as element attribute; FALSE by default.
|
|
||||||
//! Cannot be combined with HasFaceId().
|
|
||||||
void SetPartId (bool theSurfId)
|
|
||||||
{
|
|
||||||
myHasPartId = theSurfId;
|
|
||||||
myHasFaceId = myHasFaceId && !myHasPartId;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Return TRUE if face Id should be written as element attribute; FALSE by default.
|
|
||||||
bool HasFaceId() const { return myHasFaceId; }
|
|
||||||
|
|
||||||
//! Set if face Id should be written as element attribute; FALSE by default.
|
|
||||||
//! Cannot be combined with HasPartId().
|
|
||||||
void SetFaceId (bool theSurfId)
|
|
||||||
{
|
|
||||||
myHasFaceId = theSurfId;
|
|
||||||
myHasPartId = myHasPartId && !myHasFaceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! Write PLY file and associated MTL material file.
|
|
||||||
//! Triangulation data should be precomputed within shapes!
|
|
||||||
//! @param[in] theDocument input document
|
|
||||||
//! @param[in] theRootLabels list of root shapes to export
|
|
||||||
//! @param[in] theLabelFilter optional filter with document nodes to export,
|
|
||||||
//! with keys defined by XCAFPrs_DocumentExplorer::DefineChildId() and filled recursively
|
|
||||||
//! (leaves and parent assembly nodes at all levels);
|
|
||||||
//! when not NULL, all nodes not included into the map will be ignored
|
|
||||||
//! @param[in] theFileInfo map with file metadata to put into PLY header section
|
|
||||||
//! @param[in] theProgress optional progress indicator
|
|
||||||
//! @return FALSE on file writing failure
|
|
||||||
Standard_EXPORT virtual bool Perform (const Handle(TDocStd_Document)& theDocument,
|
|
||||||
const TDF_LabelSequence& theRootLabels,
|
|
||||||
const TColStd_MapOfAsciiString* theLabelFilter,
|
|
||||||
const TColStd_IndexedDataMapOfStringString& theFileInfo,
|
|
||||||
const Message_ProgressRange& theProgress);
|
|
||||||
|
|
||||||
//! Write PLY file and associated MTL material file.
|
|
||||||
//! Triangulation data should be precomputed within shapes!
|
|
||||||
//! @param[in] theDocument input document
|
|
||||||
//! @param[in] theFileInfo map with file metadata to put into PLY header section
|
|
||||||
//! @param[in] theProgress optional progress indicator
|
|
||||||
//! @return FALSE on file writing failure
|
|
||||||
Standard_EXPORT virtual bool Perform (const Handle(TDocStd_Document)& theDocument,
|
|
||||||
const TColStd_IndexedDataMapOfStringString& theFileInfo,
|
|
||||||
const Message_ProgressRange& theProgress);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//! Return TRUE if face mesh should be skipped (e.g. because it is invalid or empty).
|
|
||||||
Standard_EXPORT virtual Standard_Boolean toSkipFaceMesh (const RWMesh_FaceIterator& theFaceIter);
|
|
||||||
|
|
||||||
//! Collect face triangulation info.
|
|
||||||
//! @param[in] theFace face to process
|
|
||||||
//! @param[in,out] theNbNodes overall number of triangulation nodes (should be appended)
|
|
||||||
//! @param[in,out] theNbElems overall number of triangulation elements (should be appended)
|
|
||||||
Standard_EXPORT virtual void addFaceInfo (const RWMesh_FaceIterator& theFace,
|
|
||||||
Standard_Integer& theNbNodes,
|
|
||||||
Standard_Integer& theNbElems);
|
|
||||||
|
|
||||||
//! Write the shape.
|
|
||||||
//! @param[in] theWriter PLY writer context
|
|
||||||
//! @param[in] thePSentry progress sentry
|
|
||||||
//! @param[in] theWriteStep export step, 0 for vertex attributes, 1 for elements
|
|
||||||
//! @param[in] theLabel document label to process
|
|
||||||
//! @param[in] theParentTrsf parent node transformation
|
|
||||||
//! @param[in] theParentStyle parent node style
|
|
||||||
Standard_EXPORT virtual bool writeShape (RWPly_PlyWriterContext& theWriter,
|
|
||||||
Message_LazyProgressScope& thePSentry,
|
|
||||||
const Standard_Integer theWriteStep,
|
|
||||||
const TDF_Label& theLabel,
|
|
||||||
const TopLoc_Location& theParentTrsf,
|
|
||||||
const XCAFPrs_Style& theParentStyle);
|
|
||||||
|
|
||||||
//! Write face triangle vertices and attributes.
|
|
||||||
//! @param[in] theWriter PLY writer context
|
|
||||||
//! @param[in] thePSentry progress sentry
|
|
||||||
//! @param[in] theFace current face
|
|
||||||
//! @return FALSE on writing file error
|
|
||||||
Standard_EXPORT virtual bool writeNodes (RWPly_PlyWriterContext& theWriter,
|
|
||||||
Message_LazyProgressScope& thePSentry,
|
|
||||||
const RWMesh_FaceIterator& theFace);
|
|
||||||
|
|
||||||
//! Write face triangles indices.
|
|
||||||
//! @param[in] theWriter PLY writer context
|
|
||||||
//! @param[in] thePSentry progress sentry
|
|
||||||
//! @param[in] theFace current face
|
|
||||||
//! @return FALSE on writing file error
|
|
||||||
Standard_EXPORT virtual bool writeIndices (RWPly_PlyWriterContext& theWriter,
|
|
||||||
Message_LazyProgressScope& thePSentry,
|
|
||||||
const RWMesh_FaceIterator& theFace);
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
TCollection_AsciiString myFile; //!< output PLY file
|
|
||||||
RWMesh_CoordinateSystemConverter myCSTrsf; //!< transformation from OCCT to PLY coordinate system
|
|
||||||
XCAFPrs_Style myDefaultStyle; //!< default material definition to be used for nodes with only color defined
|
|
||||||
Standard_Boolean myIsDoublePrec;
|
|
||||||
Standard_Boolean myHasNormals;
|
|
||||||
Standard_Boolean myHasColors;
|
|
||||||
Standard_Boolean myHasTexCoords;
|
|
||||||
Standard_Boolean myHasPartId;
|
|
||||||
Standard_Boolean myHasFaceId;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _RWPly_CafWriter_HeaderFiler
|
|
@@ -1,324 +0,0 @@
|
|||||||
// Copyright (c) 2022 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 <RWPly_PlyWriterContext.hxx>
|
|
||||||
|
|
||||||
#include <Message.hxx>
|
|
||||||
#include <NCollection_IndexedMap.hxx>
|
|
||||||
#include <OSD_FileSystem.hxx>
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : splitLines
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
static void splitLines (const TCollection_AsciiString& theString,
|
|
||||||
NCollection_IndexedMap<TCollection_AsciiString>& theLines)
|
|
||||||
{
|
|
||||||
if (theString.IsEmpty())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Integer aLineFrom = 1;
|
|
||||||
for (Standard_Integer aCharIter = 1;; ++aCharIter)
|
|
||||||
{
|
|
||||||
const char aChar = theString.Value (aCharIter);
|
|
||||||
if (aChar != '\r'
|
|
||||||
&& aChar != '\n'
|
|
||||||
&& aCharIter != theString.Length())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aLineFrom != aCharIter)
|
|
||||||
{
|
|
||||||
TCollection_AsciiString aLine = theString.SubString (aLineFrom, aCharIter);
|
|
||||||
aLine.RightAdjust();
|
|
||||||
theLines.Add (aLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aCharIter == theString.Length())
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (aChar == '\r'
|
|
||||||
&& theString.Value (aCharIter + 1) == '\n')
|
|
||||||
{
|
|
||||||
// CRLF
|
|
||||||
++aCharIter;
|
|
||||||
}
|
|
||||||
aLineFrom = aCharIter + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================================================================
|
|
||||||
// Function : RWPly_PlyWriterContext
|
|
||||||
// Purpose :
|
|
||||||
// ================================================================
|
|
||||||
RWPly_PlyWriterContext::RWPly_PlyWriterContext()
|
|
||||||
: myNbHeaderVerts (0),
|
|
||||||
myNbHeaderElems (0),
|
|
||||||
myNbVerts (0),
|
|
||||||
myNbElems (0),
|
|
||||||
mySurfId (0),
|
|
||||||
myVertOffset (0),
|
|
||||||
myIsDoublePrec (false),
|
|
||||||
myHasNormals (false),
|
|
||||||
myHasColors (false),
|
|
||||||
myHasTexCoords (false),
|
|
||||||
myHasSurfId (false)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================================================================
|
|
||||||
// Function : ~RWPly_PlyWriterContext
|
|
||||||
// Purpose :
|
|
||||||
// ================================================================
|
|
||||||
RWPly_PlyWriterContext::~RWPly_PlyWriterContext()
|
|
||||||
{
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================================================================
|
|
||||||
// Function : Open
|
|
||||||
// Purpose :
|
|
||||||
// ================================================================
|
|
||||||
bool RWPly_PlyWriterContext::Open (const TCollection_AsciiString& theName,
|
|
||||||
const std::shared_ptr<std::ostream>& theStream)
|
|
||||||
{
|
|
||||||
myName = theName;
|
|
||||||
myNbHeaderVerts = myNbHeaderElems = 0;
|
|
||||||
myNbVerts = myNbElems = 0;
|
|
||||||
if (theStream.get() != nullptr)
|
|
||||||
{
|
|
||||||
myStream = theStream;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
|
|
||||||
myStream = aFileSystem->OpenOStream (theName, std::ios::out | std::ios::binary);
|
|
||||||
if (myStream.get() == NULL || !myStream->good())
|
|
||||||
{
|
|
||||||
myStream.reset();
|
|
||||||
Message::SendFail() << "Error: file cannot be created\n" << theName;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================================================================
|
|
||||||
// Function : Close
|
|
||||||
// Purpose :
|
|
||||||
// ================================================================
|
|
||||||
bool RWPly_PlyWriterContext::Close (bool theIsAborted)
|
|
||||||
{
|
|
||||||
if (myStream.get() == nullptr)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
myStream->flush();
|
|
||||||
bool aResult = myStream->good();
|
|
||||||
if (!aResult)
|
|
||||||
{
|
|
||||||
Message::SendFail() << "Error: file cannot be written\n" << myName;
|
|
||||||
}
|
|
||||||
else if (!theIsAborted)
|
|
||||||
{
|
|
||||||
if (myNbVerts != myNbHeaderVerts)
|
|
||||||
{
|
|
||||||
Message::SendFail() << "Error: written less number of vertices (" << myNbVerts << ") than specified in PLY header (" << myNbHeaderVerts << ")";
|
|
||||||
}
|
|
||||||
else if (myNbElems != myNbHeaderElems)
|
|
||||||
{
|
|
||||||
Message::SendFail() << "Error: written less number of elements (" << myNbElems << ") than specified in PLY header (" << myNbHeaderElems << ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
myStream.reset();
|
|
||||||
return aResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================================================================
|
|
||||||
// Function : WriteHeader
|
|
||||||
// Purpose :
|
|
||||||
// ================================================================
|
|
||||||
bool RWPly_PlyWriterContext::WriteHeader (const Standard_Integer theNbNodes,
|
|
||||||
const Standard_Integer theNbElems,
|
|
||||||
const TColStd_IndexedDataMapOfStringString& theFileInfo)
|
|
||||||
{
|
|
||||||
if (myStream.get() == nullptr)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
myNbHeaderVerts = theNbNodes;
|
|
||||||
myNbHeaderElems = theNbElems;
|
|
||||||
*myStream << "ply\n"
|
|
||||||
"format ascii 1.0\n"
|
|
||||||
"comment Exported by Open CASCADE Technology [dev.opencascade.org]\n";
|
|
||||||
for (TColStd_IndexedDataMapOfStringString::Iterator aKeyValueIter (theFileInfo); aKeyValueIter.More(); aKeyValueIter.Next())
|
|
||||||
{
|
|
||||||
NCollection_IndexedMap<TCollection_AsciiString> aKeyLines, aValLines;
|
|
||||||
splitLines (aKeyValueIter.Key(), aKeyLines);
|
|
||||||
splitLines (aKeyValueIter.Value(), aValLines);
|
|
||||||
for (Standard_Integer aLineIter = 1; aLineIter <= aKeyLines.Extent(); ++aLineIter)
|
|
||||||
{
|
|
||||||
const TCollection_AsciiString& aLine = aKeyLines.FindKey (aLineIter);
|
|
||||||
*myStream << (aLineIter > 1 ? "\n" : "") << "comment " << aLine;
|
|
||||||
}
|
|
||||||
*myStream << (!aKeyLines.IsEmpty() ? ":" : "comment ");
|
|
||||||
for (Standard_Integer aLineIter = 1; aLineIter <= aValLines.Extent(); ++aLineIter)
|
|
||||||
{
|
|
||||||
const TCollection_AsciiString& aLine = aValLines.FindKey (aLineIter);
|
|
||||||
*myStream << (aLineIter > 1 ? "\n" : "") << "comment " << aLine;
|
|
||||||
}
|
|
||||||
*myStream << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
*myStream << "element vertex " << theNbNodes<< "\n";
|
|
||||||
if (myIsDoublePrec)
|
|
||||||
{
|
|
||||||
*myStream << "property double x\n"
|
|
||||||
"property double y\n"
|
|
||||||
"property double z\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*myStream << "property float x\n"
|
|
||||||
"property float y\n"
|
|
||||||
"property float z\n";
|
|
||||||
}
|
|
||||||
if (myHasNormals)
|
|
||||||
{
|
|
||||||
*myStream << "property float nx\n"
|
|
||||||
"property float ny\n"
|
|
||||||
"property float nz\n";
|
|
||||||
}
|
|
||||||
if (myHasTexCoords)
|
|
||||||
{
|
|
||||||
*myStream << "property float s\n"
|
|
||||||
"property float t\n";
|
|
||||||
}
|
|
||||||
if (myHasColors)
|
|
||||||
{
|
|
||||||
*myStream << "property uchar red\n"
|
|
||||||
"property uchar green\n"
|
|
||||||
"property uchar blue\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (theNbElems > 0)
|
|
||||||
{
|
|
||||||
*myStream << "element face " << theNbElems << "\n"
|
|
||||||
"property list uchar uint vertex_indices\n";
|
|
||||||
if (myHasSurfId)
|
|
||||||
{
|
|
||||||
*myStream << "property uint SurfaceID\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*myStream << "end_header\n";
|
|
||||||
return myStream->good();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================================================================
|
|
||||||
// Function : WriteVertex
|
|
||||||
// Purpose :
|
|
||||||
// ================================================================
|
|
||||||
bool RWPly_PlyWriterContext::WriteVertex (const gp_Pnt& thePoint,
|
|
||||||
const Graphic3d_Vec3& theNorm,
|
|
||||||
const Graphic3d_Vec2& theUV,
|
|
||||||
const Graphic3d_Vec4ub& theColor)
|
|
||||||
{
|
|
||||||
if (myStream.get() == nullptr)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (myIsDoublePrec)
|
|
||||||
{
|
|
||||||
*myStream << (double )thePoint.X() << " " << (double )thePoint.Y() << " " << (double )thePoint.Z();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*myStream << (float )thePoint.X() << " " << (float )thePoint.Y() << " " << (float )thePoint.Z();
|
|
||||||
}
|
|
||||||
if (myHasNormals)
|
|
||||||
{
|
|
||||||
*myStream << " " << (float )theNorm.x() << " " << (float )theNorm.y() << " " << (float )theNorm.z();
|
|
||||||
}
|
|
||||||
if (myHasTexCoords)
|
|
||||||
{
|
|
||||||
*myStream << " " << (float )theUV.x() << " " << (float )theUV.y();
|
|
||||||
}
|
|
||||||
if (myHasColors)
|
|
||||||
{
|
|
||||||
*myStream << " " << (int )theColor.r() << " " << (int )theColor.g() << " " << (int )theColor.b();
|
|
||||||
}
|
|
||||||
*myStream << "\n";
|
|
||||||
if (++myNbVerts > myNbHeaderVerts)
|
|
||||||
{
|
|
||||||
throw Standard_OutOfRange ("RWPly_PlyWriterContext::WriteVertex() - number of vertices is greater than defined");
|
|
||||||
}
|
|
||||||
return myStream->good();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================================================================
|
|
||||||
// Function : WriteTriangle
|
|
||||||
// Purpose :
|
|
||||||
// ================================================================
|
|
||||||
bool RWPly_PlyWriterContext::WriteTriangle (const Graphic3d_Vec3i& theTri)
|
|
||||||
{
|
|
||||||
if (myStream.get() == nullptr)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Graphic3d_Vec3i aTri = Graphic3d_Vec3i(myVertOffset) + theTri;
|
|
||||||
*myStream << "3 " << aTri[0] << " " << aTri[1] << " " << aTri[2];
|
|
||||||
if (myHasSurfId)
|
|
||||||
{
|
|
||||||
*myStream << " " << mySurfId;
|
|
||||||
}
|
|
||||||
*myStream << "\n";
|
|
||||||
if (++myNbElems > myNbHeaderElems)
|
|
||||||
{
|
|
||||||
throw Standard_OutOfRange ("RWPly_PlyWriterContext::WriteTriangle() - number of elements is greater than defined");
|
|
||||||
}
|
|
||||||
return myStream->good();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================================================================
|
|
||||||
// Function : WriteQuad
|
|
||||||
// Purpose :
|
|
||||||
// ================================================================
|
|
||||||
bool RWPly_PlyWriterContext::WriteQuad (const Graphic3d_Vec4i& theQuad)
|
|
||||||
{
|
|
||||||
if (myStream.get() == nullptr)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Graphic3d_Vec4i aQuad = Graphic3d_Vec4i(myVertOffset) + theQuad;
|
|
||||||
*myStream << "4 " << aQuad[0] << " " << aQuad[1] << " " << aQuad[2] << " " << aQuad[3];
|
|
||||||
if (myHasSurfId)
|
|
||||||
{
|
|
||||||
*myStream << " " << mySurfId;
|
|
||||||
}
|
|
||||||
*myStream << "\n";
|
|
||||||
if (++myNbElems > myNbHeaderElems)
|
|
||||||
{
|
|
||||||
throw Standard_OutOfRange ("RWPly_PlyWriterContext::WriteQuad() - number of elements is greater than defined");
|
|
||||||
}
|
|
||||||
return myStream->good();
|
|
||||||
}
|
|
@@ -1,142 +0,0 @@
|
|||||||
// Copyright (c) 2022 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 _RWPly_PlyWriterContext_HeaderFiler
|
|
||||||
#define _RWPly_PlyWriterContext_HeaderFiler
|
|
||||||
|
|
||||||
#include <Graphic3d_Vec.hxx>
|
|
||||||
#include <gp_Pnt.hxx>
|
|
||||||
#include <TCollection_AsciiString.hxx>
|
|
||||||
#include <TColStd_IndexedDataMapOfStringString.hxx>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
//! Auxiliary low-level tool writing PLY file.
|
|
||||||
class RWPly_PlyWriterContext
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! Empty constructor.
|
|
||||||
Standard_EXPORT RWPly_PlyWriterContext();
|
|
||||||
|
|
||||||
//! Destructor, will emit error message if file was not closed.
|
|
||||||
Standard_EXPORT ~RWPly_PlyWriterContext();
|
|
||||||
|
|
||||||
public: //! @name vertex attributes parameters
|
|
||||||
|
|
||||||
//! Return TRUE if vertex position should be stored with double floating point precision; FALSE by default.
|
|
||||||
bool IsDoublePrecision() const { return myIsDoublePrec; }
|
|
||||||
|
|
||||||
//! Set if vertex position should be stored with double floating point precision.
|
|
||||||
void SetDoublePrecision (bool theDoublePrec) { myIsDoublePrec = theDoublePrec; }
|
|
||||||
|
|
||||||
//! Return TRUE if normals should be written as vertex attribute; FALSE by default.
|
|
||||||
bool HasNormals() const { return myHasNormals; }
|
|
||||||
|
|
||||||
//! Set if normals should be written.
|
|
||||||
void SetNormals (const bool theHasNormals) { myHasNormals = theHasNormals; }
|
|
||||||
|
|
||||||
//! Return TRUE if UV / texture coordinates should be written as vertex attribute; FALSE by default.
|
|
||||||
bool HasTexCoords() const { return myHasTexCoords; }
|
|
||||||
|
|
||||||
//! Set if UV / texture coordinates should be written.
|
|
||||||
void SetTexCoords (const bool theHasTexCoords) { myHasTexCoords = theHasTexCoords; }
|
|
||||||
|
|
||||||
//! Return TRUE if point colors should be written as vertex attribute; FALSE by default.
|
|
||||||
bool HasColors() const { return myHasColors; }
|
|
||||||
|
|
||||||
//! Set if point colors should be written.
|
|
||||||
void SetColors (bool theToWrite) { myHasColors = theToWrite; }
|
|
||||||
|
|
||||||
public: //! @name element attributes parameters
|
|
||||||
|
|
||||||
//! Return TRUE if surface Id should be written as element attribute; FALSE by default.
|
|
||||||
bool HasSurfaceId() const { return myHasSurfId; }
|
|
||||||
|
|
||||||
//! Set if surface Id should be written as element attribute; FALSE by default.
|
|
||||||
void SetSurfaceId (bool theSurfId) { myHasSurfId = theSurfId; }
|
|
||||||
|
|
||||||
public: //! @name writing into file
|
|
||||||
|
|
||||||
//! Return TRUE if file has been opened.
|
|
||||||
bool IsOpened() const { return myStream.get() != nullptr; }
|
|
||||||
|
|
||||||
//! Open file for writing.
|
|
||||||
Standard_EXPORT bool Open (const TCollection_AsciiString& theName,
|
|
||||||
const std::shared_ptr<std::ostream>& theStream = std::shared_ptr<std::ostream>());
|
|
||||||
|
|
||||||
//! Write the header.
|
|
||||||
//! @param[in] theNbNodes number of vertex nodes
|
|
||||||
//! @param[in] theNbElems number of mesh elements
|
|
||||||
//! @param[in] theFileInfo optional comments
|
|
||||||
Standard_EXPORT bool WriteHeader (const Standard_Integer theNbNodes,
|
|
||||||
const Standard_Integer theNbElems,
|
|
||||||
const TColStd_IndexedDataMapOfStringString& theFileInfo);
|
|
||||||
|
|
||||||
//! Write single point with all attributes.
|
|
||||||
//! @param[in] thePoint 3D point coordinates
|
|
||||||
//! @param[in] theNorm surface normal direction at the point
|
|
||||||
//! @param[in] theUV surface/texture UV coordinates
|
|
||||||
//! @param[in] theColor RGB color values
|
|
||||||
Standard_EXPORT bool WriteVertex (const gp_Pnt& thePoint,
|
|
||||||
const Graphic3d_Vec3& theNorm,
|
|
||||||
const Graphic3d_Vec2& theUV,
|
|
||||||
const Graphic3d_Vec4ub& theColor);
|
|
||||||
|
|
||||||
//! Return number of written vertices.
|
|
||||||
Standard_Integer NbWrittenVertices() const { return myNbVerts; }
|
|
||||||
|
|
||||||
//! Return vertex offset to be applied to element indices; 0 by default.
|
|
||||||
Standard_Integer VertexOffset() const { return myVertOffset; }
|
|
||||||
|
|
||||||
//! Set vertex offset to be applied to element indices.
|
|
||||||
void SetVertexOffset (Standard_Integer theOffset) { myVertOffset = theOffset; }
|
|
||||||
|
|
||||||
//! Return surface id to write with element; 0 by default.
|
|
||||||
Standard_Integer SurfaceId() const { return mySurfId; }
|
|
||||||
|
|
||||||
//! Set surface id to write with element.
|
|
||||||
void SetSurfaceId (Standard_Integer theSurfId) { mySurfId = theSurfId; }
|
|
||||||
|
|
||||||
//! Writing a triangle.
|
|
||||||
Standard_EXPORT bool WriteTriangle (const Graphic3d_Vec3i& theTri);
|
|
||||||
|
|
||||||
//! Writing a quad.
|
|
||||||
Standard_EXPORT bool WriteQuad (const Graphic3d_Vec4i& theQuad);
|
|
||||||
|
|
||||||
//! Return number of written elements.
|
|
||||||
Standard_Integer NbWrittenElements() const { return myNbElems; }
|
|
||||||
|
|
||||||
//! Correctly close the file.
|
|
||||||
//! @return FALSE in case of writing error
|
|
||||||
Standard_EXPORT bool Close (bool theIsAborted = false);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::shared_ptr<std::ostream> myStream;
|
|
||||||
TCollection_AsciiString myName;
|
|
||||||
Standard_Integer myNbHeaderVerts;
|
|
||||||
Standard_Integer myNbHeaderElems;
|
|
||||||
Standard_Integer myNbVerts;
|
|
||||||
Standard_Integer myNbElems;
|
|
||||||
Standard_Integer mySurfId;
|
|
||||||
Standard_Integer myVertOffset;
|
|
||||||
bool myIsDoublePrec;
|
|
||||||
bool myHasNormals;
|
|
||||||
bool myHasColors;
|
|
||||||
bool myHasTexCoords;
|
|
||||||
bool myHasSurfId;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _RWPly_PlyWriterContext_HeaderFiler
|
|
@@ -529,8 +529,6 @@
|
|||||||
#include <RWStepVisual_RWPresentationStyleByContext.hxx>
|
#include <RWStepVisual_RWPresentationStyleByContext.hxx>
|
||||||
#include <RWStepVisual_RWPresentationView.hxx>
|
#include <RWStepVisual_RWPresentationView.hxx>
|
||||||
#include <RWStepVisual_RWPresentedItemRepresentation.hxx>
|
#include <RWStepVisual_RWPresentedItemRepresentation.hxx>
|
||||||
#include <RWStepVisual_RWRepositionedTessellatedGeometricSet.hxx>
|
|
||||||
#include <RWStepVisual_RWRepositionedTessellatedItem.hxx>
|
|
||||||
#include <RWStepVisual_RWStyledItem.hxx>
|
#include <RWStepVisual_RWStyledItem.hxx>
|
||||||
#include <RWStepVisual_RWSurfaceSideStyle.hxx>
|
#include <RWStepVisual_RWSurfaceSideStyle.hxx>
|
||||||
#include <RWStepVisual_RWSurfaceStyleBoundary.hxx>
|
#include <RWStepVisual_RWSurfaceStyleBoundary.hxx>
|
||||||
@@ -1090,8 +1088,6 @@
|
|||||||
#include <StepVisual_PresentationStyleByContext.hxx>
|
#include <StepVisual_PresentationStyleByContext.hxx>
|
||||||
#include <StepVisual_PresentationView.hxx>
|
#include <StepVisual_PresentationView.hxx>
|
||||||
#include <StepVisual_PresentedItemRepresentation.hxx>
|
#include <StepVisual_PresentedItemRepresentation.hxx>
|
||||||
#include <StepVisual_RepositionedTessellatedGeometricSet.hxx>
|
|
||||||
#include <StepVisual_RepositionedTessellatedItem.hxx>
|
|
||||||
#include <StepVisual_StyledItem.hxx>
|
#include <StepVisual_StyledItem.hxx>
|
||||||
#include <StepVisual_SurfaceSideStyle.hxx>
|
#include <StepVisual_SurfaceSideStyle.hxx>
|
||||||
#include <StepVisual_SurfaceStyleBoundary.hxx>
|
#include <StepVisual_SurfaceStyleBoundary.hxx>
|
||||||
@@ -5894,13 +5890,7 @@ void RWStepAP214_GeneralModule::FillSharedCase(const Standard_Integer CN,
|
|||||||
tool.Share(anent, iter);
|
tool.Share(anent, iter);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 802:
|
|
||||||
{
|
|
||||||
DeclareAndCast(StepVisual_RepositionedTessellatedGeometricSet, anEnt, ent);
|
|
||||||
RWStepVisual_RWRepositionedTessellatedGeometricSet aTool;
|
|
||||||
aTool.Share(anEnt, iter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default : break;
|
default : break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8156,12 +8146,6 @@ Standard_Boolean RWStepAP214_GeneralModule::NewVoid
|
|||||||
case 801:
|
case 801:
|
||||||
ent = new StepKinematics_MechanismStateRepresentation;
|
ent = new StepKinematics_MechanismStateRepresentation;
|
||||||
break;
|
break;
|
||||||
case 802:
|
|
||||||
ent = new StepVisual_RepositionedTessellatedGeometricSet;
|
|
||||||
break;
|
|
||||||
case 803:
|
|
||||||
ent = new StepVisual_RepositionedTessellatedItem;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
@@ -8842,8 +8826,6 @@ Standard_Integer RWStepAP214_GeneralModule::CategoryNumber
|
|||||||
case 798: return cataux;
|
case 798: return cataux;
|
||||||
case 800: return catsh;
|
case 800: return catsh;
|
||||||
case 801: return cataux;
|
case 801: return cataux;
|
||||||
case 802: return cataux;
|
|
||||||
case 803: return cataux;
|
|
||||||
default : break;
|
default : break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -258,8 +258,6 @@ IMPLEMENT_STANDARD_RTTIEXT(RWStepAP214_ReadWriteModule,StepData_ReadWriteModule)
|
|||||||
#include <StepVisual_PresentationStyleAssignment.hxx>
|
#include <StepVisual_PresentationStyleAssignment.hxx>
|
||||||
#include <StepVisual_PresentationStyleByContext.hxx>
|
#include <StepVisual_PresentationStyleByContext.hxx>
|
||||||
#include <StepVisual_PresentationView.hxx>
|
#include <StepVisual_PresentationView.hxx>
|
||||||
#include <StepVisual_RepositionedTessellatedGeometricSet.hxx>
|
|
||||||
#include <StepVisual_RepositionedTessellatedItem.hxx>
|
|
||||||
#include <StepBasic_Product.hxx>
|
#include <StepBasic_Product.hxx>
|
||||||
#include <StepBasic_ProductCategory.hxx>
|
#include <StepBasic_ProductCategory.hxx>
|
||||||
#include <StepBasic_ProductContext.hxx>
|
#include <StepBasic_ProductContext.hxx>
|
||||||
@@ -656,8 +654,6 @@ IMPLEMENT_STANDARD_RTTIEXT(RWStepAP214_ReadWriteModule,StepData_ReadWriteModule)
|
|||||||
#include <RWStepVisual_RWPresentationStyleAssignment.hxx>
|
#include <RWStepVisual_RWPresentationStyleAssignment.hxx>
|
||||||
#include <RWStepVisual_RWPresentationStyleByContext.hxx>
|
#include <RWStepVisual_RWPresentationStyleByContext.hxx>
|
||||||
#include <RWStepVisual_RWPresentationView.hxx>
|
#include <RWStepVisual_RWPresentationView.hxx>
|
||||||
#include <RWStepVisual_RWRepositionedTessellatedGeometricSet.hxx>
|
|
||||||
#include <RWStepVisual_RWRepositionedTessellatedItem.hxx>
|
|
||||||
#include <RWStepBasic_RWProduct.hxx>
|
#include <RWStepBasic_RWProduct.hxx>
|
||||||
#include <RWStepBasic_RWProductCategory.hxx>
|
#include <RWStepBasic_RWProductCategory.hxx>
|
||||||
#include <RWStepBasic_RWProductContext.hxx>
|
#include <RWStepBasic_RWProductContext.hxx>
|
||||||
@@ -2209,8 +2205,6 @@ static TCollection_AsciiString Reco_AnnotationPlane("ANNOTATION_PLANE");
|
|||||||
static TCollection_AsciiString Reco_TessellatedAnnotationOccurrence("TESSELLATED_ANNOTATION_OCCURRENCE");
|
static TCollection_AsciiString Reco_TessellatedAnnotationOccurrence("TESSELLATED_ANNOTATION_OCCURRENCE");
|
||||||
static TCollection_AsciiString Reco_TessellatedGeometricSet("TESSELLATED_GEOMETRIC_SET");
|
static TCollection_AsciiString Reco_TessellatedGeometricSet("TESSELLATED_GEOMETRIC_SET");
|
||||||
static TCollection_AsciiString Reco_TessellatedCurveSet("TESSELLATED_CURVE_SET");
|
static TCollection_AsciiString Reco_TessellatedCurveSet("TESSELLATED_CURVE_SET");
|
||||||
static TCollection_AsciiString Reco_TessellatedItem("TESSELLATED_ITEM");
|
|
||||||
static TCollection_AsciiString Reco_RepositionedTessellatedItem("REPOSITIONED_TESSELLATED_ITEM");
|
|
||||||
static TCollection_AsciiString Reco_CoordinatesList("COORDINATES_LIST");
|
static TCollection_AsciiString Reco_CoordinatesList("COORDINATES_LIST");
|
||||||
static TCollection_AsciiString Reco_ConstructiveGeometryRepresentation("CONSTRUCTIVE_GEOMETRY_REPRESENTATION");
|
static TCollection_AsciiString Reco_ConstructiveGeometryRepresentation("CONSTRUCTIVE_GEOMETRY_REPRESENTATION");
|
||||||
static TCollection_AsciiString Reco_ConstructiveGeometryRepresentationRelationship("CONSTRUCTIVE_GEOMETRY_REPRESENTATION_RELATIONSHIP");
|
static TCollection_AsciiString Reco_ConstructiveGeometryRepresentationRelationship("CONSTRUCTIVE_GEOMETRY_REPRESENTATION_RELATIONSHIP");
|
||||||
@@ -3041,7 +3035,6 @@ RWStepAP214_ReadWriteModule::RWStepAP214_ReadWriteModule ()
|
|||||||
typenums.Bind(Reco_LinearFlexibleLinkRepresentation, 798);
|
typenums.Bind(Reco_LinearFlexibleLinkRepresentation, 798);
|
||||||
typenums.Bind(Reco_KinematicPair, 799);
|
typenums.Bind(Reco_KinematicPair, 799);
|
||||||
typenums.Bind(Reco_MechanismStateRepresentation, 801);
|
typenums.Bind(Reco_MechanismStateRepresentation, 801);
|
||||||
typenums.Bind(Reco_RepositionedTessellatedItem, 803);
|
|
||||||
|
|
||||||
|
|
||||||
// SHORT NAMES
|
// SHORT NAMES
|
||||||
@@ -3834,22 +3827,13 @@ Standard_Integer RWStepAP214_ReadWriteModule::CaseStep
|
|||||||
types(5).IsEqual(StepType(624))))) {
|
types(5).IsEqual(StepType(624))))) {
|
||||||
return 705;
|
return 705;
|
||||||
}
|
}
|
||||||
else if ((types(1).IsEqual(StepType(4))) &&
|
if ((types(1).IsEqual(StepType(4))) &&
|
||||||
(types(2).IsEqual(StepType(7))) &&
|
(types(2).IsEqual(StepType(7))) &&
|
||||||
(types(3).IsEqual(StepType(144))) &&
|
(types(3).IsEqual(StepType(144))) &&
|
||||||
(types(4).IsEqual(StepType(247))) &&
|
(types(4).IsEqual(StepType(247))) &&
|
||||||
(types(5).IsEqual(StepType(270))))
|
(types(5).IsEqual(StepType(270)))) {
|
||||||
{
|
|
||||||
return 719;
|
return 719;
|
||||||
}
|
}
|
||||||
else if ((types(1).IsEqual(StepType(144))) &&
|
|
||||||
(types(2).IsEqual(StepType(803))) &&
|
|
||||||
(types(3).IsEqual(StepType(247))) &&
|
|
||||||
(types(4).IsEqual(StepType(709))) &&
|
|
||||||
(types(5).IsEqual(StepType(708))))
|
|
||||||
{
|
|
||||||
return 802;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (NbComp == 4) {
|
else if (NbComp == 4) {
|
||||||
if ((types(1).IsEqual(StepType(161))) &&
|
if ((types(1).IsEqual(StepType(161))) &&
|
||||||
@@ -4919,7 +4903,6 @@ const TCollection_AsciiString& RWStepAP214_ReadWriteModule::StepType
|
|||||||
case 704: return Reco_AnnotationPlane;
|
case 704: return Reco_AnnotationPlane;
|
||||||
|
|
||||||
case 707 : return Reco_TessellatedAnnotationOccurrence;
|
case 707 : return Reco_TessellatedAnnotationOccurrence;
|
||||||
case 708 : return Reco_TessellatedItem;
|
|
||||||
case 709 : return Reco_TessellatedGeometricSet;
|
case 709 : return Reco_TessellatedGeometricSet;
|
||||||
|
|
||||||
case 710 : return Reco_TessellatedCurveSet;
|
case 710 : return Reco_TessellatedCurveSet;
|
||||||
@@ -5013,7 +4996,7 @@ const TCollection_AsciiString& RWStepAP214_ReadWriteModule::StepType
|
|||||||
case 798: return Reco_LinearFlexibleLinkRepresentation;
|
case 798: return Reco_LinearFlexibleLinkRepresentation;
|
||||||
case 799: return Reco_KinematicPair;
|
case 799: return Reco_KinematicPair;
|
||||||
case 801: return Reco_MechanismStateRepresentation;
|
case 801: return Reco_MechanismStateRepresentation;
|
||||||
case 803: return Reco_RepositionedTessellatedItem;
|
|
||||||
default : return PasReco;
|
default : return PasReco;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5344,13 +5327,6 @@ Standard_Boolean RWStepAP214_ReadWriteModule::ComplexType(const Standard_Integer
|
|||||||
types.Append(StepType(759));
|
types.Append(StepType(759));
|
||||||
types.Append(StepType(247));
|
types.Append(StepType(247));
|
||||||
break;
|
break;
|
||||||
case 802:
|
|
||||||
types.Append(StepType(144));
|
|
||||||
types.Append(StepType(803));
|
|
||||||
types.Append(StepType(247));
|
|
||||||
types.Append(StepType(709));
|
|
||||||
types.Append(StepType(708));
|
|
||||||
break;
|
|
||||||
default: return Standard_False;
|
default: return Standard_False;
|
||||||
}
|
}
|
||||||
return Standard_True;
|
return Standard_True;
|
||||||
@@ -10497,20 +10473,6 @@ void RWStepAP214_ReadWriteModule::ReadStep(const Standard_Integer CN,
|
|||||||
tool.ReadStep(data, num, ach, anent);
|
tool.ReadStep(data, num, ach, anent);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 802:
|
|
||||||
{
|
|
||||||
DeclareAndCast(StepVisual_RepositionedTessellatedGeometricSet, anEnt, ent);
|
|
||||||
RWStepVisual_RWRepositionedTessellatedGeometricSet aTool;
|
|
||||||
aTool.ReadStep(data, num, ach, anEnt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 803:
|
|
||||||
{
|
|
||||||
DeclareAndCast(StepVisual_RepositionedTessellatedItem, anEnt, ent);
|
|
||||||
RWStepVisual_RWRepositionedTessellatedItem aTool;
|
|
||||||
aTool.ReadStep(data, num, ach, anEnt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ach->AddFail("Type Mismatch when reading - Entity");
|
ach->AddFail("Type Mismatch when reading - Entity");
|
||||||
@@ -15934,20 +15896,7 @@ void RWStepAP214_ReadWriteModule::WriteStep(const Standard_Integer CN,
|
|||||||
tool.WriteStep(SW, anent);
|
tool.WriteStep(SW, anent);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 802:
|
|
||||||
{
|
|
||||||
DeclareAndCast(StepVisual_RepositionedTessellatedGeometricSet, anEnt, ent);
|
|
||||||
RWStepVisual_RWRepositionedTessellatedGeometricSet aTool;
|
|
||||||
aTool.WriteStep(SW, anEnt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 803:
|
|
||||||
{
|
|
||||||
DeclareAndCast(StepVisual_RepositionedTessellatedItem, anEnt, ent);
|
|
||||||
RWStepVisual_RWRepositionedTessellatedItem aTool;
|
|
||||||
aTool.WriteStep(SW, anEnt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -106,10 +106,6 @@ RWStepVisual_RWPresentationView.cxx
|
|||||||
RWStepVisual_RWPresentationView.hxx
|
RWStepVisual_RWPresentationView.hxx
|
||||||
RWStepVisual_RWPresentedItemRepresentation.cxx
|
RWStepVisual_RWPresentedItemRepresentation.cxx
|
||||||
RWStepVisual_RWPresentedItemRepresentation.hxx
|
RWStepVisual_RWPresentedItemRepresentation.hxx
|
||||||
RWStepVisual_RWRepositionedTessellatedGeometricSet.cxx
|
|
||||||
RWStepVisual_RWRepositionedTessellatedGeometricSet.hxx
|
|
||||||
RWStepVisual_RWRepositionedTessellatedItem.cxx
|
|
||||||
RWStepVisual_RWRepositionedTessellatedItem.hxx
|
|
||||||
RWStepVisual_RWStyledItem.cxx
|
RWStepVisual_RWStyledItem.cxx
|
||||||
RWStepVisual_RWStyledItem.hxx
|
RWStepVisual_RWStyledItem.hxx
|
||||||
RWStepVisual_RWSurfaceSideStyle.cxx
|
RWStepVisual_RWSurfaceSideStyle.cxx
|
||||||
|
@@ -1,99 +0,0 @@
|
|||||||
// Copyright (c) 2022 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 <RWStepVisual_RWRepositionedTessellatedGeometricSet.hxx>
|
|
||||||
|
|
||||||
#include <Interface_Check.hxx>
|
|
||||||
#include <Interface_EntityIterator.hxx>
|
|
||||||
#include <StepData_StepReaderData.hxx>
|
|
||||||
#include <StepData_StepWriter.hxx>
|
|
||||||
#include <StepRepr_RepresentationItem.hxx>
|
|
||||||
#include <StepVisual_HArray1OfPresentationStyleAssignment.hxx>
|
|
||||||
#include <StepVisual_PresentationStyleAssignment.hxx>
|
|
||||||
#include <StepVisual_RepositionedTessellatedGeometricSet.hxx>
|
|
||||||
#include <StepGeom_Axis2Placement3d.hxx>
|
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : ReadStep
|
|
||||||
//purpose :
|
|
||||||
//=======================================================================
|
|
||||||
void RWStepVisual_RWRepositionedTessellatedGeometricSet::ReadStep
|
|
||||||
(const Handle(StepData_StepReaderData)& theData,
|
|
||||||
const Standard_Integer theNum,
|
|
||||||
Handle(Interface_Check)& theAch,
|
|
||||||
const Handle(StepVisual_RepositionedTessellatedGeometricSet)& theEnt) const
|
|
||||||
{
|
|
||||||
Standard_Integer aNum = 0;
|
|
||||||
theData->NamedForComplex("REPOSITIONED_TESSELLATED_ITEM", theNum, aNum, theAch);
|
|
||||||
if (!theData->CheckNbParams(aNum, 1, theAch, "location"))
|
|
||||||
return;
|
|
||||||
Handle(StepGeom_Axis2Placement3d) aLocation;
|
|
||||||
theData->ReadEntity(aNum,1,"location",theAch,STANDARD_TYPE(StepGeom_Axis2Placement3d), aLocation);
|
|
||||||
|
|
||||||
theData->NamedForComplex("REPRESENTATION_ITEM", theNum, aNum, theAch);
|
|
||||||
if (!theData->CheckNbParams(aNum, 1, theAch, "name"))
|
|
||||||
return;
|
|
||||||
Handle(TCollection_HAsciiString) aName;
|
|
||||||
theData->ReadString (aNum, 1, "name", theAch, aName);
|
|
||||||
|
|
||||||
theData->NamedForComplex("TESSELLATED_GEOMETRIC_SET", theNum, aNum, theAch);
|
|
||||||
NCollection_Handle<StepVisual_Array1OfTessellatedItem> anItems;
|
|
||||||
Standard_Integer aNSub2;
|
|
||||||
if (theData->ReadSubList (aNum,1,"items",theAch,aNSub2)) {
|
|
||||||
Standard_Integer aNb2 = theData->NbParams(aNSub2);
|
|
||||||
anItems = new StepVisual_Array1OfTessellatedItem(1, aNb2);
|
|
||||||
for (Standard_Integer i2 = 1; i2 <= aNb2; i2 ++) {
|
|
||||||
Handle(StepVisual_TessellatedItem) anItem;
|
|
||||||
if (theData->ReadEntity (aNSub2,i2,"item",theAch,STANDARD_TYPE(StepVisual_TessellatedItem), anItem))
|
|
||||||
anItems->SetValue(i2,anItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
theEnt->Init(aName, anItems, aLocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : WriteStep
|
|
||||||
//purpose :
|
|
||||||
//=======================================================================
|
|
||||||
void RWStepVisual_RWRepositionedTessellatedGeometricSet::WriteStep
|
|
||||||
(StepData_StepWriter& theSW,
|
|
||||||
const Handle(StepVisual_RepositionedTessellatedGeometricSet)& theEnt) const
|
|
||||||
{
|
|
||||||
theSW.StartEntity("GEOMETRIC_REPRESENTATION_ITEM");
|
|
||||||
theSW.StartEntity("REPOSITIONED_TESSELLATED_ITEM");
|
|
||||||
theSW.Send(theEnt->Location());
|
|
||||||
theSW.StartEntity("REPRESENTATION_ITEM");
|
|
||||||
theSW.Send(theEnt->Name());
|
|
||||||
theSW.StartEntity("TESSELLATED_GEOMETRIC_SET");
|
|
||||||
theSW.OpenSub();
|
|
||||||
for(StepVisual_Array1OfTessellatedItem::Iterator anIter(*theEnt->Items());
|
|
||||||
anIter.More(); anIter.Next())
|
|
||||||
{
|
|
||||||
theSW.Send(anIter.Value());
|
|
||||||
}
|
|
||||||
theSW.CloseSub();
|
|
||||||
theSW.StartEntity("TESSELLATED_ITEM");
|
|
||||||
}
|
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : Share
|
|
||||||
//purpose :
|
|
||||||
//=======================================================================
|
|
||||||
void RWStepVisual_RWRepositionedTessellatedGeometricSet::Share(const Handle(StepVisual_RepositionedTessellatedGeometricSet)& theEnt,
|
|
||||||
Interface_EntityIterator& theIter) const
|
|
||||||
{
|
|
||||||
// Own field : children
|
|
||||||
for (Standard_Integer i = 1; i <= theEnt->Items()->Length(); i++)
|
|
||||||
theIter.AddItem(theEnt->Items()->Value(i));
|
|
||||||
theIter.AddItem(theEnt->Location());
|
|
||||||
}
|
|
@@ -1,50 +0,0 @@
|
|||||||
// Copyright (c) 2022 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 _RWStepVisual_RWRepositionedTessellatedGeometricSet_HeaderFile
|
|
||||||
#define _RWStepVisual_RWRepositionedTessellatedGeometricSet_HeaderFile
|
|
||||||
|
|
||||||
#include <Standard_DefineAlloc.hxx>
|
|
||||||
#include <Standard_Handle.hxx>
|
|
||||||
|
|
||||||
class StepData_StepReaderData;
|
|
||||||
class Interface_Check;
|
|
||||||
class StepVisual_RepositionedTessellatedGeometricSet;
|
|
||||||
class StepData_StepWriter;
|
|
||||||
class Interface_EntityIterator;
|
|
||||||
|
|
||||||
//! Read & Write tool for complex RepositionedTessellatedGeometricSet
|
|
||||||
class RWStepVisual_RWRepositionedTessellatedGeometricSet
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
DEFINE_STANDARD_ALLOC
|
|
||||||
|
|
||||||
//! Empty constructor
|
|
||||||
RWStepVisual_RWRepositionedTessellatedGeometricSet() {};
|
|
||||||
|
|
||||||
//! Reads RepositionedTessellatedGeometricSet
|
|
||||||
Standard_EXPORT void ReadStep (const Handle(StepData_StepReaderData)& theData,
|
|
||||||
const Standard_Integer theNum,
|
|
||||||
Handle(Interface_Check)& theAch,
|
|
||||||
const Handle(StepVisual_RepositionedTessellatedGeometricSet)& theEnt) const;
|
|
||||||
|
|
||||||
//! Writes RepositionedTessellatedGeometricSet
|
|
||||||
Standard_EXPORT void WriteStep (StepData_StepWriter& theSW,
|
|
||||||
const Handle(StepVisual_RepositionedTessellatedGeometricSet)& theEnt) const;
|
|
||||||
|
|
||||||
//! Fills data for graph (shared items)
|
|
||||||
Standard_EXPORT void Share (const Handle(StepVisual_RepositionedTessellatedGeometricSet)& theEnt,
|
|
||||||
Interface_EntityIterator& theIter) const;
|
|
||||||
};
|
|
||||||
#endif // _RWStepVisual_RWRepositionedTessellatedGeometricSet_HeaderFile
|
|
@@ -1,58 +0,0 @@
|
|||||||
// Copyright (c) 2022 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 <RWStepVisual_RWRepositionedTessellatedItem.hxx>
|
|
||||||
|
|
||||||
#include <Interface_Check.hxx>
|
|
||||||
#include <StepData_StepReaderData.hxx>
|
|
||||||
#include <StepData_StepWriter.hxx>
|
|
||||||
#include <StepVisual_RepositionedTessellatedItem.hxx>
|
|
||||||
#include <StepGeom_Axis2Placement3d.hxx>
|
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : ReadStep
|
|
||||||
//purpose :
|
|
||||||
//=======================================================================
|
|
||||||
void RWStepVisual_RWRepositionedTessellatedItem::ReadStep
|
|
||||||
(const Handle(StepData_StepReaderData)& theData,
|
|
||||||
const Standard_Integer theNum,
|
|
||||||
Handle(Interface_Check)& theAch,
|
|
||||||
const Handle(StepVisual_RepositionedTessellatedItem)& theEnt) const
|
|
||||||
{
|
|
||||||
// --- Number of Parameter Control ---
|
|
||||||
if (!theData->CheckNbParams(theNum,2,theAch,"tessellated_item"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// --- inherited field : name ---
|
|
||||||
Handle(TCollection_HAsciiString) aName;
|
|
||||||
theData->ReadString (theNum,1,"name",theAch,aName);
|
|
||||||
// --- inherited field : location ---
|
|
||||||
Handle(StepGeom_Axis2Placement3d) aLocation;
|
|
||||||
theData->ReadEntity(theNum,2,"location", theAch, STANDARD_TYPE(StepGeom_Axis2Placement3d),aLocation);
|
|
||||||
|
|
||||||
//--- Initialisation of the read entity ---
|
|
||||||
theEnt->Init(aName, aLocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : WriteStep
|
|
||||||
//purpose :
|
|
||||||
//=======================================================================
|
|
||||||
void RWStepVisual_RWRepositionedTessellatedItem::WriteStep
|
|
||||||
(StepData_StepWriter& theSW,
|
|
||||||
const Handle(StepVisual_RepositionedTessellatedItem)& theEnt) const
|
|
||||||
{
|
|
||||||
// --- inherited field name ---
|
|
||||||
theSW.Send(theEnt->Name());
|
|
||||||
theSW.Send(theEnt->Location());
|
|
||||||
}
|
|
@@ -1,46 +0,0 @@
|
|||||||
// Copyright (c) 2022 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 _RWStepVisual_RWRepositionedTessellatedItem_HeaderFile
|
|
||||||
#define _RWStepVisual_RWRepositionedTessellatedItem_HeaderFile
|
|
||||||
|
|
||||||
#include <Standard.hxx>
|
|
||||||
#include <Standard_DefineAlloc.hxx>
|
|
||||||
#include <Standard_Handle.hxx>
|
|
||||||
|
|
||||||
class StepData_StepReaderData;
|
|
||||||
class Interface_Check;
|
|
||||||
class StepVisual_RepositionedTessellatedItem;
|
|
||||||
class StepData_StepWriter;
|
|
||||||
|
|
||||||
//! Read & Write tool for RepositionedTessellatedItem
|
|
||||||
class RWStepVisual_RWRepositionedTessellatedItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
DEFINE_STANDARD_ALLOC
|
|
||||||
|
|
||||||
//! Empty constructor
|
|
||||||
RWStepVisual_RWRepositionedTessellatedItem() {};
|
|
||||||
|
|
||||||
//! Reads RepositionedTessellatedItem
|
|
||||||
Standard_EXPORT void ReadStep (const Handle(StepData_StepReaderData)& theData,
|
|
||||||
const Standard_Integer theNum,
|
|
||||||
Handle(Interface_Check)& theAch,
|
|
||||||
const Handle(StepVisual_RepositionedTessellatedItem)& theEnt) const;
|
|
||||||
|
|
||||||
//! Writes RepositionedTessellatedItem
|
|
||||||
Standard_EXPORT void WriteStep (StepData_StepWriter& theSW,
|
|
||||||
const Handle(StepVisual_RepositionedTessellatedItem)& theEnt) const;
|
|
||||||
};
|
|
||||||
#endif // _RWStepVisual_RWRepositionedTessellatedItem_HeaderFile
|
|
@@ -147,6 +147,12 @@ Handle(Poly_Triangulation) RWStl::ReadFile (const OSD_Path& theFile,
|
|||||||
Handle(Poly_Triangulation) RWStl::ReadBinary (const OSD_Path& theFile,
|
Handle(Poly_Triangulation) RWStl::ReadBinary (const OSD_Path& theFile,
|
||||||
const Message_ProgressRange& theProgress)
|
const Message_ProgressRange& theProgress)
|
||||||
{
|
{
|
||||||
|
OSD_File aFile(theFile);
|
||||||
|
if (!aFile.Exists())
|
||||||
|
{
|
||||||
|
return Handle(Poly_Triangulation)();
|
||||||
|
}
|
||||||
|
|
||||||
TCollection_AsciiString aPath;
|
TCollection_AsciiString aPath;
|
||||||
theFile.SystemName (aPath);
|
theFile.SystemName (aPath);
|
||||||
|
|
||||||
@@ -173,24 +179,31 @@ Handle(Poly_Triangulation) RWStl::ReadBinary (const OSD_Path& theFile,
|
|||||||
Handle(Poly_Triangulation) RWStl::ReadAscii (const OSD_Path& theFile,
|
Handle(Poly_Triangulation) RWStl::ReadAscii (const OSD_Path& theFile,
|
||||||
const Message_ProgressRange& theProgress)
|
const Message_ProgressRange& theProgress)
|
||||||
{
|
{
|
||||||
TCollection_AsciiString aPath;
|
OSD_File aFile (theFile);
|
||||||
theFile.SystemName (aPath);
|
if (!aFile.Exists())
|
||||||
|
|
||||||
const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
|
|
||||||
std::shared_ptr<std::istream> aStream = aFileSystem->OpenIStream (aPath, std::ios::in | std::ios::binary);
|
|
||||||
if (aStream.get() == NULL)
|
|
||||||
{
|
{
|
||||||
return Handle(Poly_Triangulation)();
|
return Handle(Poly_Triangulation)();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TCollection_AsciiString aPath;
|
||||||
|
theFile.SystemName (aPath);
|
||||||
|
|
||||||
|
std::filebuf aBuf;
|
||||||
|
OSD_OpenStream (aBuf, aPath, std::ios::in | std::ios::binary);
|
||||||
|
if (!aBuf.is_open())
|
||||||
|
{
|
||||||
|
return Handle(Poly_Triangulation)();
|
||||||
|
}
|
||||||
|
Standard_IStream aStream (&aBuf);
|
||||||
|
|
||||||
// get length of file to feed progress indicator
|
// get length of file to feed progress indicator
|
||||||
aStream->seekg (0, aStream->end);
|
aStream.seekg (0, aStream.end);
|
||||||
std::streampos theEnd = aStream->tellg();
|
std::streampos theEnd = aStream.tellg();
|
||||||
aStream->seekg (0, aStream->beg);
|
aStream.seekg (0, aStream.beg);
|
||||||
|
|
||||||
Reader aReader;
|
Reader aReader;
|
||||||
Standard_ReadLineBuffer aBuffer (THE_BUFFER_SIZE);
|
Standard_ReadLineBuffer aBuffer (THE_BUFFER_SIZE);
|
||||||
if (!aReader.ReadAscii (*aStream, aBuffer, theEnd, theProgress))
|
if (!aReader.ReadAscii (aStream, aBuffer, theEnd, theProgress))
|
||||||
{
|
{
|
||||||
return Handle(Poly_Triangulation)();
|
return Handle(Poly_Triangulation)();
|
||||||
}
|
}
|
||||||
@@ -338,7 +351,7 @@ Standard_Boolean RWStl::writeBinary (const Handle(Poly_Triangulation)& theMesh,
|
|||||||
FILE* theFile,
|
FILE* theFile,
|
||||||
const Message_ProgressRange& theProgress)
|
const Message_ProgressRange& theProgress)
|
||||||
{
|
{
|
||||||
char aHeader[80] = "STL Exported by Open CASCADE Technology [dev.opencascade.org]";
|
char aHeader[80] = "STL Exported by OpenCASCADE [www.opencascade.com]";
|
||||||
if (fwrite (aHeader, 1, 80, theFile) != 80)
|
if (fwrite (aHeader, 1, 80, theFile) != 80)
|
||||||
{
|
{
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
|
@@ -204,7 +204,6 @@
|
|||||||
#include <StepVisual_PlanarBox.hxx>
|
#include <StepVisual_PlanarBox.hxx>
|
||||||
#include <StepVisual_PresentationLayerAssignment.hxx>
|
#include <StepVisual_PresentationLayerAssignment.hxx>
|
||||||
#include <StepVisual_PresentationStyleByContext.hxx>
|
#include <StepVisual_PresentationStyleByContext.hxx>
|
||||||
#include <StepVisual_RepositionedTessellatedGeometricSet.hxx>
|
|
||||||
#include <StepVisual_StyleContextSelect.hxx>
|
#include <StepVisual_StyleContextSelect.hxx>
|
||||||
#include <StepVisual_StyledItem.hxx>
|
#include <StepVisual_StyledItem.hxx>
|
||||||
#include <StepVisual_ViewVolume.hxx>
|
#include <StepVisual_ViewVolume.hxx>
|
||||||
@@ -1869,25 +1868,6 @@ Standard_Boolean readPMIPresentation(const Handle(Standard_Transient)& thePresen
|
|||||||
Handle(StepVisual_TessellatedGeometricSet) aTessSet = Handle(StepVisual_TessellatedGeometricSet)::DownCast(aTessItem);
|
Handle(StepVisual_TessellatedGeometricSet) aTessSet = Handle(StepVisual_TessellatedGeometricSet)::DownCast(aTessItem);
|
||||||
if (aTessSet.IsNull())
|
if (aTessSet.IsNull())
|
||||||
continue;
|
continue;
|
||||||
gp_Trsf aTransf;
|
|
||||||
if (aTessSet->IsKind(STANDARD_TYPE(StepVisual_RepositionedTessellatedGeometricSet)))
|
|
||||||
{
|
|
||||||
Handle(StepVisual_RepositionedTessellatedGeometricSet) aRTGS =
|
|
||||||
Handle(StepVisual_RepositionedTessellatedGeometricSet)::DownCast(aTessSet);
|
|
||||||
Handle(Geom_Axis2Placement) aLocation = StepToGeom::MakeAxis2Placement(aRTGS->Location());
|
|
||||||
if (!aLocation.IsNull())
|
|
||||||
{
|
|
||||||
const gp_Ax3 anAx3Orig = gp::XOY();
|
|
||||||
const gp_Ax3 anAx3Targ(aLocation->Ax2());
|
|
||||||
if (anAx3Targ.Location().SquareDistance(anAx3Orig.Location()) >= Precision::SquareConfusion() ||
|
|
||||||
!anAx3Targ.Direction().IsEqual(anAx3Orig.Direction(), Precision::Angular()) ||
|
|
||||||
!anAx3Targ.XDirection().IsEqual(anAx3Orig.XDirection(), Precision::Angular()) ||
|
|
||||||
!anAx3Targ.YDirection().IsEqual(anAx3Orig.YDirection(), Precision::Angular()))
|
|
||||||
{
|
|
||||||
aTransf.SetTransformation(anAx3Targ, anAx3Orig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NCollection_Handle<StepVisual_Array1OfTessellatedItem> aListItems = aTessSet->Items();
|
NCollection_Handle<StepVisual_Array1OfTessellatedItem> aListItems = aTessSet->Items();
|
||||||
Standard_Integer nb = aListItems.IsNull() ? 0 : aListItems->Length();
|
Standard_Integer nb = aListItems.IsNull() ? 0 : aListItems->Length();
|
||||||
Handle(StepVisual_TessellatedCurveSet) aTessCurve;
|
Handle(StepVisual_TessellatedCurveSet) aTessCurve;
|
||||||
@@ -1933,7 +1913,7 @@ Standard_Boolean readPMIPresentation(const Handle(Standard_Transient)& thePresen
|
|||||||
}
|
}
|
||||||
aB.Add(aComp, aCurW);
|
aB.Add(aComp, aCurW);
|
||||||
}
|
}
|
||||||
anAnnotationShape = aComp.Moved(aTransf);
|
anAnnotationShape = aComp;
|
||||||
}
|
}
|
||||||
if (!anAnnotationShape.IsNull())
|
if (!anAnnotationShape.IsNull())
|
||||||
{
|
{
|
||||||
|
@@ -155,22 +155,13 @@ public:
|
|||||||
DEFINE_STANDARD_ALLOC
|
DEFINE_STANDARD_ALLOC
|
||||||
|
|
||||||
//! Registers this callback object in the current error handler (if found).
|
//! Registers this callback object in the current error handler (if found).
|
||||||
#if defined(OCC_CONVERT_SIGNALS)
|
void RegisterCallback();
|
||||||
Standard_EXPORT
|
|
||||||
#endif
|
|
||||||
void RegisterCallback();
|
|
||||||
|
|
||||||
//! Unregisters this callback object from the error handler.
|
//! Unregisters this callback object from the error handler.
|
||||||
#if defined(OCC_CONVERT_SIGNALS)
|
void UnregisterCallback();
|
||||||
Standard_EXPORT
|
|
||||||
#endif
|
|
||||||
void UnregisterCallback();
|
|
||||||
|
|
||||||
//! Destructor
|
//! Destructor
|
||||||
#if defined(OCC_CONVERT_SIGNALS)
|
virtual ~Callback();
|
||||||
Standard_EXPORT
|
|
||||||
#endif
|
|
||||||
virtual ~Callback();
|
|
||||||
|
|
||||||
//! The callback function to perform necessary callback action.
|
//! The callback function to perform necessary callback action.
|
||||||
//! Called by the exception handler when it is being destroyed but
|
//! Called by the exception handler when it is being destroyed but
|
||||||
@@ -180,10 +171,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
//! Empty constructor
|
//! Empty constructor
|
||||||
#if defined(OCC_CONVERT_SIGNALS)
|
Callback();
|
||||||
Standard_EXPORT
|
|
||||||
#endif
|
|
||||||
Callback();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Standard_Address myHandler;
|
Standard_Address myHandler;
|
||||||
|
@@ -18,11 +18,24 @@
|
|||||||
|
|
||||||
#include <BRepBndLib.hxx>
|
#include <BRepBndLib.hxx>
|
||||||
#include <BRepMesh_DiscretFactory.hxx>
|
#include <BRepMesh_DiscretFactory.hxx>
|
||||||
|
#include <BRepMesh_DiscretRoot.hxx>
|
||||||
#include <BRepTools.hxx>
|
#include <BRepTools.hxx>
|
||||||
#include <BRep_Tool.hxx>
|
#include <BRep_Tool.hxx>
|
||||||
|
#include <GeomAbs_SurfaceType.hxx>
|
||||||
|
#include <GeomLib.hxx>
|
||||||
|
#include <gp_XYZ.hxx>
|
||||||
|
#include <Poly.hxx>
|
||||||
|
#include <Poly_Connect.hxx>
|
||||||
|
#include <Poly_Triangulation.hxx>
|
||||||
|
#include <Precision.hxx>
|
||||||
#include <Prs3d.hxx>
|
#include <Prs3d.hxx>
|
||||||
#include <Prs3d_Drawer.hxx>
|
#include <Prs3d_Drawer.hxx>
|
||||||
|
#include <TColgp_Array1OfPnt.hxx>
|
||||||
|
#include <TColgp_Array1OfPnt2d.hxx>
|
||||||
|
#include <TopAbs_Orientation.hxx>
|
||||||
#include <TopLoc_Location.hxx>
|
#include <TopLoc_Location.hxx>
|
||||||
|
#include <TShort_HArray1OfShortReal.hxx>
|
||||||
|
#include <TShort_Array1OfShortReal.hxx>
|
||||||
#include <TopExp_Explorer.hxx>
|
#include <TopExp_Explorer.hxx>
|
||||||
#include <TopoDS.hxx>
|
#include <TopoDS.hxx>
|
||||||
#include <TopoDS_Face.hxx>
|
#include <TopoDS_Face.hxx>
|
||||||
@@ -119,6 +132,66 @@ Standard_Boolean StdPrs_ToolTriangulatedShape::IsClosed (const TopoDS_Shape& the
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : ComputeNormals
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void StdPrs_ToolTriangulatedShape::ComputeNormals (const TopoDS_Face& theFace,
|
||||||
|
const Handle(Poly_Triangulation)& theTris,
|
||||||
|
Poly_Connect& thePolyConnect)
|
||||||
|
{
|
||||||
|
if (theTris.IsNull()
|
||||||
|
|| theTris->HasNormals())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// take in face the surface location
|
||||||
|
const TopoDS_Face aZeroFace = TopoDS::Face (theFace.Located (TopLoc_Location()));
|
||||||
|
Handle(Geom_Surface) aSurf = BRep_Tool::Surface (aZeroFace);
|
||||||
|
if (!theTris->HasUVNodes() || aSurf.IsNull())
|
||||||
|
{
|
||||||
|
// compute normals by averaging triangulation normals sharing the same vertex
|
||||||
|
Poly::ComputeNormals (theTris);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Standard_Real aTol = Precision::Confusion();
|
||||||
|
Standard_Integer aTri[3];
|
||||||
|
gp_Dir aNorm;
|
||||||
|
theTris->AddNormals();
|
||||||
|
for (Standard_Integer aNodeIter = 1; aNodeIter <= theTris->NbNodes(); ++aNodeIter)
|
||||||
|
{
|
||||||
|
// try to retrieve normal from real surface first, when UV coordinates are available
|
||||||
|
if (GeomLib::NormEstim (aSurf, theTris->UVNode (aNodeIter), aTol, aNorm) > 1)
|
||||||
|
{
|
||||||
|
if (thePolyConnect.Triangulation() != theTris)
|
||||||
|
{
|
||||||
|
thePolyConnect.Load (theTris);
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute flat normals
|
||||||
|
gp_XYZ eqPlan (0.0, 0.0, 0.0);
|
||||||
|
for (thePolyConnect.Initialize (aNodeIter); thePolyConnect.More(); thePolyConnect.Next())
|
||||||
|
{
|
||||||
|
theTris->Triangle (thePolyConnect.Value()).Get (aTri[0], aTri[1], aTri[2]);
|
||||||
|
const gp_XYZ v1 (theTris->Node (aTri[1]).Coord() - theTris->Node (aTri[0]).Coord());
|
||||||
|
const gp_XYZ v2 (theTris->Node (aTri[2]).Coord() - theTris->Node (aTri[1]).Coord());
|
||||||
|
const gp_XYZ vv = v1 ^ v2;
|
||||||
|
const Standard_Real aMod = vv.Modulus();
|
||||||
|
if (aMod >= aTol)
|
||||||
|
{
|
||||||
|
eqPlan += vv / aMod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const Standard_Real aModMax = eqPlan.Modulus();
|
||||||
|
aNorm = (aModMax > aTol) ? gp_Dir (eqPlan) : gp::DZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
theTris->SetNormal (aNodeIter, aNorm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : Normal
|
//function : Normal
|
||||||
//purpose :
|
//purpose :
|
||||||
|
@@ -14,13 +14,19 @@
|
|||||||
#ifndef _StdPrs_ToolTriangulatedShape_HeaderFile
|
#ifndef _StdPrs_ToolTriangulatedShape_HeaderFile
|
||||||
#define _StdPrs_ToolTriangulatedShape_HeaderFile
|
#define _StdPrs_ToolTriangulatedShape_HeaderFile
|
||||||
|
|
||||||
#include <BRepLib_ToolTriangulatedShape.hxx>
|
#include <Poly_Connect.hxx>
|
||||||
|
#include <Poly_Triangulation.hxx>
|
||||||
|
#include <Prs3d_Drawer.hxx>
|
||||||
|
#include <Standard.hxx>
|
||||||
|
#include <Standard_Macro.hxx>
|
||||||
#include <TColgp_Array1OfDir.hxx>
|
#include <TColgp_Array1OfDir.hxx>
|
||||||
|
|
||||||
|
class TopoDS_Face;
|
||||||
class TopoDS_Shape;
|
class TopoDS_Shape;
|
||||||
class Prs3d_Drawer;
|
class Prs3d_Drawer;
|
||||||
|
class Poly_Triangulation;
|
||||||
|
|
||||||
class StdPrs_ToolTriangulatedShape: public BRepLib_ToolTriangulatedShape
|
class StdPrs_ToolTriangulatedShape
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -32,6 +38,26 @@ public:
|
|||||||
//! @return true if shape is closed manifold Solid or compound of such Solids. <br>
|
//! @return true if shape is closed manifold Solid or compound of such Solids. <br>
|
||||||
Standard_EXPORT static Standard_Boolean IsClosed (const TopoDS_Shape& theShape);
|
Standard_EXPORT static Standard_Boolean IsClosed (const TopoDS_Shape& theShape);
|
||||||
|
|
||||||
|
//! Computes nodal normals for Poly_Triangulation structure using UV coordinates and surface.
|
||||||
|
//! Does nothing if triangulation already defines normals.
|
||||||
|
//! @param theFace [in] the face
|
||||||
|
//! @param theTris [in] the definition of a face triangulation
|
||||||
|
static void ComputeNormals (const TopoDS_Face& theFace,
|
||||||
|
const Handle(Poly_Triangulation)& theTris)
|
||||||
|
{
|
||||||
|
Poly_Connect aPolyConnect;
|
||||||
|
ComputeNormals (theFace, theTris, aPolyConnect);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Computes nodal normals for Poly_Triangulation structure using UV coordinates and surface.
|
||||||
|
//! Does nothing if triangulation already defines normals.
|
||||||
|
//! @param theFace [in] the face
|
||||||
|
//! @param theTris [in] the definition of a face triangulation
|
||||||
|
//! @param thePolyConnect [in,out] optional, initialized tool for exploring triangulation
|
||||||
|
Standard_EXPORT static void ComputeNormals (const TopoDS_Face& theFace,
|
||||||
|
const Handle(Poly_Triangulation)& theTris,
|
||||||
|
Poly_Connect& thePolyConnect);
|
||||||
|
|
||||||
//! Evaluate normals for a triangle of a face.
|
//! Evaluate normals for a triangle of a face.
|
||||||
//! @param[in] theFace the face.
|
//! @param[in] theFace the face.
|
||||||
//! @param[in] thePolyConnect the definition of a face triangulation.
|
//! @param[in] thePolyConnect the definition of a face triangulation.
|
||||||
|
@@ -738,8 +738,6 @@ static Standard_CString schemaAP242DIS = "AP242_MANAGED_MODEL_BASED_3D_ENGINEERI
|
|||||||
#include <StepVisual_TessellatedItem.hxx>
|
#include <StepVisual_TessellatedItem.hxx>
|
||||||
#include <StepVisual_TessellatedGeometricSet.hxx>
|
#include <StepVisual_TessellatedGeometricSet.hxx>
|
||||||
#include <StepVisual_TessellatedCurveSet.hxx>
|
#include <StepVisual_TessellatedCurveSet.hxx>
|
||||||
#include <StepVisual_RepositionedTessellatedGeometricSet.hxx>
|
|
||||||
#include <StepVisual_RepositionedTessellatedItem.hxx>
|
|
||||||
#include <StepVisual_CoordinatesList.hxx>
|
#include <StepVisual_CoordinatesList.hxx>
|
||||||
#include <StepRepr_CharacterizedRepresentation.hxx>
|
#include <StepRepr_CharacterizedRepresentation.hxx>
|
||||||
#include <StepRepr_ConstructiveGeometryRepresentation.hxx>
|
#include <StepRepr_ConstructiveGeometryRepresentation.hxx>
|
||||||
@@ -1628,8 +1626,6 @@ StepAP214_Protocol::StepAP214_Protocol ()
|
|||||||
types.Bind(STANDARD_TYPE(StepKinematics_LinearFlexibleLinkRepresentation), 798);
|
types.Bind(STANDARD_TYPE(StepKinematics_LinearFlexibleLinkRepresentation), 798);
|
||||||
types.Bind(STANDARD_TYPE(StepKinematics_ActuatedKinPairAndOrderKinPair), 800);
|
types.Bind(STANDARD_TYPE(StepKinematics_ActuatedKinPairAndOrderKinPair), 800);
|
||||||
types.Bind(STANDARD_TYPE(StepKinematics_MechanismStateRepresentation), 801);
|
types.Bind(STANDARD_TYPE(StepKinematics_MechanismStateRepresentation), 801);
|
||||||
types.Bind(STANDARD_TYPE(StepVisual_RepositionedTessellatedGeometricSet), 802);
|
|
||||||
types.Bind(STANDARD_TYPE(StepVisual_RepositionedTessellatedItem), 803);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -14,8 +14,22 @@
|
|||||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
// commercial license or contractual agreement.
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
#include <StepFile_Read.hxx>
|
// StepFile_Read
|
||||||
|
|
||||||
|
// routine assurant l enchainement des operations de lecture d un fichier
|
||||||
|
// STEP dans un StepModel, en fonction d une cle de reconnaissance
|
||||||
|
// Retour de la fonction :
|
||||||
|
// 0 si OK (le StepModel a ete charge)
|
||||||
|
// -1 si abandon car fichier pas pu etre ouvert
|
||||||
|
// 1 si erreur en cours de lecture
|
||||||
|
|
||||||
|
// Compilation conditionnelle : concerne les mesures de performances
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <step.tab.hxx>
|
||||||
|
#include <StepFile_Read.hxx>
|
||||||
#include <StepFile_ReadData.hxx>
|
#include <StepFile_ReadData.hxx>
|
||||||
|
|
||||||
#include <Interface_Check.hxx>
|
#include <Interface_Check.hxx>
|
||||||
@@ -35,13 +49,9 @@
|
|||||||
#include <Message.hxx>
|
#include <Message.hxx>
|
||||||
#include <Message_Messenger.hxx>
|
#include <Message_Messenger.hxx>
|
||||||
|
|
||||||
#include <OSD_FileSystem.hxx>
|
#include <OSD_OpenFile.hxx>
|
||||||
#include <OSD_Timer.hxx>
|
#include <OSD_Timer.hxx>
|
||||||
|
|
||||||
#include "step.tab.hxx"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef OCCT_DEBUG
|
#ifdef OCCT_DEBUG
|
||||||
#define CHRONOMESURE
|
#define CHRONOMESURE
|
||||||
#endif
|
#endif
|
||||||
@@ -63,15 +73,14 @@ static Standard_Integer StepFile_Read (const char* theName,
|
|||||||
const Handle(StepData_FileRecognizer)& theRecogData)
|
const Handle(StepData_FileRecognizer)& theRecogData)
|
||||||
{
|
{
|
||||||
// if stream is not provided, open file stream here
|
// if stream is not provided, open file stream here
|
||||||
std::istream* aStreamPtr = theIStream;
|
std::istream *aStreamPtr = theIStream;
|
||||||
std::shared_ptr<std::istream> aFileStream;
|
std::ifstream aFileStream;
|
||||||
if (aStreamPtr == nullptr)
|
if (!aStreamPtr) {
|
||||||
{
|
OSD_OpenStream(aFileStream, theName, std::ios_base::in | std::ios_base::binary);
|
||||||
const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
|
aStreamPtr = &aFileStream;
|
||||||
aFileStream = aFileSystem->OpenIStream (theName, std::ios::in | std::ios::binary);
|
|
||||||
aStreamPtr = aFileStream.get();
|
|
||||||
}
|
}
|
||||||
if (aStreamPtr == nullptr || aStreamPtr->fail())
|
|
||||||
|
if (aStreamPtr->fail())
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@@ -17,9 +17,6 @@
|
|||||||
#ifndef StepFile_Read_HeaderFile
|
#ifndef StepFile_Read_HeaderFile
|
||||||
#define StepFile_Read_HeaderFile
|
#define StepFile_Read_HeaderFile
|
||||||
|
|
||||||
#include <Standard_CString.hxx>
|
|
||||||
#include <Standard_Type.hxx>
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
class StepData_StepModel;
|
class StepData_StepModel;
|
||||||
|
@@ -197,10 +197,6 @@ StepVisual_PresentedItemRepresentation.cxx
|
|||||||
StepVisual_PresentedItemRepresentation.hxx
|
StepVisual_PresentedItemRepresentation.hxx
|
||||||
StepVisual_RenderingPropertiesSelect.cxx
|
StepVisual_RenderingPropertiesSelect.cxx
|
||||||
StepVisual_RenderingPropertiesSelect.hxx
|
StepVisual_RenderingPropertiesSelect.hxx
|
||||||
StepVisual_RepositionedTessellatedGeometricSet.hxx
|
|
||||||
StepVisual_RepositionedTessellatedGeometricSet.cxx
|
|
||||||
StepVisual_RepositionedTessellatedItem.hxx
|
|
||||||
StepVisual_RepositionedTessellatedItem.cxx
|
|
||||||
StepVisual_ShadingSurfaceMethod.hxx
|
StepVisual_ShadingSurfaceMethod.hxx
|
||||||
StepVisual_StyleContextSelect.cxx
|
StepVisual_StyleContextSelect.cxx
|
||||||
StepVisual_StyleContextSelect.hxx
|
StepVisual_StyleContextSelect.hxx
|
||||||
|
@@ -1,30 +0,0 @@
|
|||||||
// Copyright (c) 2022 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 <StepVisual_RepositionedTessellatedGeometricSet.hxx>
|
|
||||||
|
|
||||||
#include <StepGeom_Axis2Placement3d.hxx>
|
|
||||||
|
|
||||||
IMPLEMENT_STANDARD_RTTIEXT(StepVisual_RepositionedTessellatedGeometricSet, StepVisual_TessellatedGeometricSet)
|
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : Init
|
|
||||||
//purpose :
|
|
||||||
//=======================================================================
|
|
||||||
void StepVisual_RepositionedTessellatedGeometricSet::Init(const Handle(TCollection_HAsciiString)& theName,
|
|
||||||
const NCollection_Handle<StepVisual_Array1OfTessellatedItem>& theItems,
|
|
||||||
const Handle(StepGeom_Axis2Placement3d)& theLocation)
|
|
||||||
{
|
|
||||||
StepVisual_TessellatedGeometricSet::Init(theName, theItems);
|
|
||||||
myLocation = theLocation;
|
|
||||||
}
|
|
@@ -1,50 +0,0 @@
|
|||||||
// Copyright (c) 2022 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 _StepVisual_RepositionedTessellatedGeometricSet_HeaderFile
|
|
||||||
#define _StepVisual_RepositionedTessellatedGeometricSet_HeaderFile
|
|
||||||
|
|
||||||
#include <StepVisual_TessellatedGeometricSet.hxx>
|
|
||||||
|
|
||||||
class StepGeom_Axis2Placement3d;
|
|
||||||
|
|
||||||
DEFINE_STANDARD_HANDLE(StepVisual_RepositionedTessellatedGeometricSet, StepVisual_TessellatedGeometricSet)
|
|
||||||
|
|
||||||
//! Representation of complex STEP entity RepositionedTessellatedGeometricSet
|
|
||||||
class StepVisual_RepositionedTessellatedGeometricSet : public StepVisual_TessellatedGeometricSet
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
DEFINE_STANDARD_ALLOC
|
|
||||||
|
|
||||||
DEFINE_STANDARD_RTTIEXT(StepVisual_RepositionedTessellatedGeometricSet, StepVisual_TessellatedGeometricSet)
|
|
||||||
|
|
||||||
//! Default constructor
|
|
||||||
StepVisual_RepositionedTessellatedGeometricSet() {};
|
|
||||||
|
|
||||||
//! Initialize all fields (own and inherited)
|
|
||||||
Standard_EXPORT void Init(const Handle(TCollection_HAsciiString)& theName,
|
|
||||||
const NCollection_Handle<StepVisual_Array1OfTessellatedItem>& theItems,
|
|
||||||
const Handle(StepGeom_Axis2Placement3d)& theLocation);
|
|
||||||
|
|
||||||
//! Returns location
|
|
||||||
Handle(StepGeom_Axis2Placement3d) Location() const { return myLocation; }
|
|
||||||
|
|
||||||
//! Sets location
|
|
||||||
void SetLocation(const Handle(StepGeom_Axis2Placement3d)& theLocation) { myLocation = theLocation; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Handle(StepGeom_Axis2Placement3d) myLocation;
|
|
||||||
};
|
|
||||||
#endif // StepVisual_RepositionedTessellatedGeometricSet_HeaderFile
|
|
@@ -1,29 +0,0 @@
|
|||||||
// Copyright (c) 2022 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 <StepVisual_RepositionedTessellatedItem.hxx>
|
|
||||||
|
|
||||||
#include <StepGeom_Axis2Placement3d.hxx>
|
|
||||||
|
|
||||||
IMPLEMENT_STANDARD_RTTIEXT(StepVisual_RepositionedTessellatedItem, StepVisual_TessellatedItem)
|
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : Init
|
|
||||||
//purpose :
|
|
||||||
//=======================================================================
|
|
||||||
void StepVisual_RepositionedTessellatedItem::Init(const Handle(TCollection_HAsciiString)& theName,
|
|
||||||
const Handle(StepGeom_Axis2Placement3d)& theLocation)
|
|
||||||
{
|
|
||||||
StepVisual_TessellatedItem::Init(theName);
|
|
||||||
myLocation = theLocation;
|
|
||||||
}
|
|
@@ -1,49 +0,0 @@
|
|||||||
// Copyright (c) 2022 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// 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 _StepVisual_RepositionedTessellatedItem_HeaderFile
|
|
||||||
#define _StepVisual_RepositionedTessellatedItem_HeaderFile
|
|
||||||
|
|
||||||
#include <StepVisual_TessellatedItem.hxx>
|
|
||||||
|
|
||||||
class StepGeom_Axis2Placement3d;
|
|
||||||
|
|
||||||
DEFINE_STANDARD_HANDLE(StepVisual_RepositionedTessellatedItem, StepVisual_TessellatedItem)
|
|
||||||
|
|
||||||
//! Representation of STEP entity RepositionedTessellatedItem
|
|
||||||
class StepVisual_RepositionedTessellatedItem : public StepVisual_TessellatedItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
DEFINE_STANDARD_RTTIEXT(StepVisual_RepositionedTessellatedItem, StepVisual_TessellatedItem)
|
|
||||||
|
|
||||||
DEFINE_STANDARD_ALLOC
|
|
||||||
|
|
||||||
//! Default constructor
|
|
||||||
StepVisual_RepositionedTessellatedItem() {};
|
|
||||||
|
|
||||||
//! Initialize all fields (own and inherited)
|
|
||||||
Standard_EXPORT void Init(const Handle(TCollection_HAsciiString)& theName,
|
|
||||||
const Handle(StepGeom_Axis2Placement3d)& theLocation);
|
|
||||||
|
|
||||||
//! Returns location
|
|
||||||
Handle(StepGeom_Axis2Placement3d) Location() const { return myLocation; }
|
|
||||||
|
|
||||||
//! Sets location
|
|
||||||
void SetLocation(const Handle(StepGeom_Axis2Placement3d)& theLocation) { myLocation = theLocation; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Handle(StepGeom_Axis2Placement3d) myLocation;
|
|
||||||
};
|
|
||||||
#endif // StepVisual_RepositionedTessellatedItem_HeaderFile
|
|
@@ -1,4 +1,3 @@
|
|||||||
RWGltf
|
RWGltf
|
||||||
RWMesh
|
RWMesh
|
||||||
RWObj
|
RWObj
|
||||||
RWPly
|
|
||||||
|
@@ -240,6 +240,8 @@ Standard_Real Units::ToSI(const Standard_Real aData,
|
|||||||
Handle(Units_Dimensions) &dim)
|
Handle(Units_Dimensions) &dim)
|
||||||
{
|
{
|
||||||
if(lastunit != aUnit ) {
|
if(lastunit != aUnit ) {
|
||||||
|
|
||||||
|
lastunit = TCollection_AsciiString(aUnit);
|
||||||
Units_UnitSentence unitsentence(aUnit);
|
Units_UnitSentence unitsentence(aUnit);
|
||||||
if(!unitsentence.IsDone()) {
|
if(!unitsentence.IsDone()) {
|
||||||
#ifdef OCCT_DEBUG
|
#ifdef OCCT_DEBUG
|
||||||
@@ -255,7 +257,6 @@ Standard_Real Units::ToSI(const Standard_Real aData,
|
|||||||
Handle(Units_ShiftedToken)::DownCast(token) ;
|
Handle(Units_ShiftedToken)::DownCast(token) ;
|
||||||
lastmove = stoken->Move();
|
lastmove = stoken->Move();
|
||||||
}
|
}
|
||||||
lastunit = TCollection_AsciiString(aUnit);
|
|
||||||
lastdimension = token->Dimensions();
|
lastdimension = token->Dimensions();
|
||||||
}
|
}
|
||||||
dim = lastdimension;
|
dim = lastdimension;
|
||||||
@@ -285,6 +286,7 @@ Standard_Real Units::FromSI(const Standard_Real aData,
|
|||||||
Handle(Units_Dimensions) &dim)
|
Handle(Units_Dimensions) &dim)
|
||||||
{
|
{
|
||||||
if(lastunit != aUnit) {
|
if(lastunit != aUnit) {
|
||||||
|
lastunit = TCollection_AsciiString(aUnit);
|
||||||
Units_UnitSentence unitsentence(aUnit);
|
Units_UnitSentence unitsentence(aUnit);
|
||||||
if(!unitsentence.IsDone()) {
|
if(!unitsentence.IsDone()) {
|
||||||
#ifdef OCCT_DEBUG
|
#ifdef OCCT_DEBUG
|
||||||
@@ -300,7 +302,6 @@ Standard_Real Units::FromSI(const Standard_Real aData,
|
|||||||
Handle(Units_ShiftedToken)::DownCast(token) ;
|
Handle(Units_ShiftedToken)::DownCast(token) ;
|
||||||
lastmove = stoken->Move();
|
lastmove = stoken->Move();
|
||||||
}
|
}
|
||||||
lastunit = TCollection_AsciiString(aUnit);
|
|
||||||
lastdimension = token->Dimensions();
|
lastdimension = token->Dimensions();
|
||||||
}
|
}
|
||||||
dim = lastdimension;
|
dim = lastdimension;
|
||||||
|
@@ -40,7 +40,6 @@
|
|||||||
#include <AIS_Shape.hxx>
|
#include <AIS_Shape.hxx>
|
||||||
#include <AIS_DisplayMode.hxx>
|
#include <AIS_DisplayMode.hxx>
|
||||||
#include <AIS_PointCloud.hxx>
|
#include <AIS_PointCloud.hxx>
|
||||||
#include <BRepLib_PointCloudShape.hxx>
|
|
||||||
#include <TColStd_MapOfInteger.hxx>
|
#include <TColStd_MapOfInteger.hxx>
|
||||||
#include <ViewerTest_AutoUpdater.hxx>
|
#include <ViewerTest_AutoUpdater.hxx>
|
||||||
#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
|
#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
|
||||||
@@ -6251,12 +6250,6 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
|
|||||||
Standard_Integer theArgNum,
|
Standard_Integer theArgNum,
|
||||||
const char** theArgs)
|
const char** theArgs)
|
||||||
{
|
{
|
||||||
if (theArgNum < 2)
|
|
||||||
{
|
|
||||||
Message::SendFail ("Syntax error: wrong number of arguments");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
|
Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
|
||||||
if (anAISContext.IsNull())
|
if (anAISContext.IsNull())
|
||||||
{
|
{
|
||||||
@@ -6264,114 +6257,83 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
TCollection_AsciiString aName;
|
// command to execute
|
||||||
TopoDS_Shape aShape;
|
enum Command
|
||||||
|
{
|
||||||
|
CloudForShape, // generate point cloud for shape
|
||||||
|
CloudSphere, // generate point cloud for generic sphere
|
||||||
|
Unknow
|
||||||
|
};
|
||||||
|
|
||||||
TCollection_AsciiString aDistribution;
|
// count number of non-optional command arguments
|
||||||
gp_Pnt aDistCenter;
|
Command aCmd = Unknow;
|
||||||
Standard_Real aDistRadius = 0.0;
|
Standard_Integer aCmdArgs = 0;
|
||||||
Standard_Integer aDistNbPoints = 0;
|
|
||||||
|
|
||||||
// parse options
|
|
||||||
bool toRandColors = false;
|
|
||||||
bool hasNormals = true, hasUV = false;
|
|
||||||
bool isDensityPoints = false;
|
|
||||||
Standard_Real aDensity = 0.0, aDist = 0.0;
|
|
||||||
Standard_Real aTol = Precision::Confusion();
|
|
||||||
for (Standard_Integer anArgIter = 1; anArgIter < theArgNum; ++anArgIter)
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgNum; ++anArgIter)
|
||||||
{
|
{
|
||||||
TCollection_AsciiString aFlag (theArgs[anArgIter]);
|
Standard_CString anArg = theArgs[anArgIter];
|
||||||
|
TCollection_AsciiString aFlag (anArg);
|
||||||
|
aFlag.LowerCase();
|
||||||
|
if (aFlag.IsRealValue (Standard_True) || aFlag.Search ("-") != 1)
|
||||||
|
{
|
||||||
|
aCmdArgs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (aCmdArgs)
|
||||||
|
{
|
||||||
|
case 2 : aCmd = CloudForShape; break;
|
||||||
|
case 7 : aCmd = CloudSphere; break;
|
||||||
|
default :
|
||||||
|
Message::SendFail ("Syntax error: wrong number of arguments! See usage:");
|
||||||
|
theDI.PrintHelp (theArgs[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse options
|
||||||
|
Standard_Boolean toRandColors = Standard_False;
|
||||||
|
Standard_Boolean hasNormals = Standard_True;
|
||||||
|
Standard_Boolean isSetArgNorm = Standard_False;
|
||||||
|
Standard_Boolean hasUV = Standard_False;
|
||||||
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgNum; ++anArgIter)
|
||||||
|
{
|
||||||
|
Standard_CString anArg = theArgs[anArgIter];
|
||||||
|
TCollection_AsciiString aFlag (anArg);
|
||||||
aFlag.LowerCase();
|
aFlag.LowerCase();
|
||||||
if (aFlag == "-randcolors"
|
if (aFlag == "-randcolors"
|
||||||
|| aFlag == "-randcolor")
|
|| aFlag == "-randcolor")
|
||||||
{
|
{
|
||||||
toRandColors = Draw::ParseOnOffIterator (theArgNum, theArgs, anArgIter);
|
if (isSetArgNorm && hasNormals)
|
||||||
|
{
|
||||||
|
Message::SendFail ("Syntax error: normals can not be enabled with colors at the same time");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
toRandColors = Standard_True;
|
||||||
|
hasNormals = Standard_False;
|
||||||
}
|
}
|
||||||
else if (aFlag == "-normals"
|
else if (aFlag == "-normals"
|
||||||
|| aFlag == "-normal")
|
|| aFlag == "-normal")
|
||||||
{
|
{
|
||||||
hasNormals = Draw::ParseOnOffIterator (theArgNum, theArgs, anArgIter);
|
if (toRandColors)
|
||||||
|
{
|
||||||
|
Message::SendFail ("Syntax error: normals can not be enabled with colors at the same time");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
isSetArgNorm = Standard_True;
|
||||||
|
hasNormals = Standard_True;
|
||||||
}
|
}
|
||||||
else if (aFlag == "-nonormals"
|
else if (aFlag == "-nonormals"
|
||||||
|| aFlag == "-nonormal")
|
|| aFlag == "-nonormal")
|
||||||
{
|
{
|
||||||
hasNormals = !Draw::ParseOnOffIterator (theArgNum, theArgs, anArgIter);
|
isSetArgNorm = Standard_True;
|
||||||
|
hasNormals = Standard_False;
|
||||||
}
|
}
|
||||||
else if (aFlag == "-uv"
|
else if (aFlag == "-uv"
|
||||||
|| aFlag == "-texels")
|
|| aFlag == "-texels")
|
||||||
{
|
{
|
||||||
hasUV = Draw::ParseOnOffIterator (theArgNum, theArgs, anArgIter);
|
hasUV = Standard_True;
|
||||||
}
|
|
||||||
else if ((aFlag == "-dist"
|
|
||||||
|| aFlag == "-distance")
|
|
||||||
&& anArgIter + 1 < theArgNum
|
|
||||||
&& Draw::ParseReal (theArgs[anArgIter + 1], aDist))
|
|
||||||
{
|
|
||||||
++anArgIter;
|
|
||||||
if (aDist < 0.0)
|
|
||||||
{
|
|
||||||
theDI << "Syntax error: -distance value should be >= 0.0";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
aDist = Max (aDist, Precision::Confusion());
|
|
||||||
}
|
|
||||||
else if ((aFlag == "-dens"
|
|
||||||
|| aFlag == "-density")
|
|
||||||
&& anArgIter + 1 < theArgNum
|
|
||||||
&& Draw::ParseReal (theArgs[anArgIter + 1], aDensity))
|
|
||||||
{
|
|
||||||
++anArgIter;
|
|
||||||
isDensityPoints = Standard_True;
|
|
||||||
if (aDensity <= 0.0)
|
|
||||||
{
|
|
||||||
theDI << "Syntax error: -density value should be > 0.0";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((aFlag == "-tol"
|
|
||||||
|| aFlag == "-tolerance")
|
|
||||||
&& anArgIter + 1 < theArgNum
|
|
||||||
&& Draw::ParseReal (theArgs[anArgIter + 1], aTol))
|
|
||||||
{
|
|
||||||
++anArgIter;
|
|
||||||
if (aTol < Precision::Confusion())
|
|
||||||
{
|
|
||||||
theDI << "Syntax error: -tol value should be >= " << Precision::Confusion();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((aFlag == "-surface"
|
|
||||||
|| aFlag == "-volume")
|
|
||||||
&& anArgIter + 5 < theArgNum)
|
|
||||||
{
|
|
||||||
aDistribution = aFlag;
|
|
||||||
aDistCenter.SetCoord (Draw::Atof (theArgs[anArgIter + 1]),
|
|
||||||
Draw::Atof (theArgs[anArgIter + 2]),
|
|
||||||
Draw::Atof (theArgs[anArgIter + 3]));
|
|
||||||
aDistRadius = Draw::Atof (theArgs[anArgIter + 4]);
|
|
||||||
aDistNbPoints = Draw::Atoi (theArgs[anArgIter + 5]);
|
|
||||||
anArgIter += 5;
|
|
||||||
}
|
|
||||||
else if (aName.IsEmpty())
|
|
||||||
{
|
|
||||||
aName = theArgs[anArgIter];
|
|
||||||
}
|
|
||||||
else if (aShape.IsNull())
|
|
||||||
{
|
|
||||||
aShape = DBRep::Get (theArgs[anArgIter]);
|
|
||||||
if (aShape.IsNull())
|
|
||||||
{
|
|
||||||
theDI << "Syntax error: invalid shape '" << theArgs[anArgIter] << "'";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
theDI << "Syntax error at '" << theArgs[anArgIter] << "'";
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Standard_CString aName = theArgs[1];
|
||||||
Graphic3d_ArrayFlags aFlags = Graphic3d_ArrayFlags_None;
|
Graphic3d_ArrayFlags aFlags = Graphic3d_ArrayFlags_None;
|
||||||
if (hasNormals)
|
if (hasNormals)
|
||||||
{
|
{
|
||||||
@@ -6388,80 +6350,125 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
|
|||||||
|
|
||||||
// generate arbitrary set of points
|
// generate arbitrary set of points
|
||||||
Handle(Graphic3d_ArrayOfPoints) anArrayPoints;
|
Handle(Graphic3d_ArrayOfPoints) anArrayPoints;
|
||||||
if (!aShape.IsNull())
|
if (aCmd == CloudForShape)
|
||||||
{
|
{
|
||||||
class PointCloudPntFiller : public BRepLib_PointCloudShape
|
Standard_CString aShapeName = theArgs[2];
|
||||||
|
TopoDS_Shape aShape = DBRep::Get (aShapeName);
|
||||||
|
|
||||||
|
if (aShape.IsNull())
|
||||||
{
|
{
|
||||||
public:
|
Message::SendFail() << "Error: no shape with name '" << aShapeName << "' found";
|
||||||
PointCloudPntFiller (Standard_Real theTol) : BRepLib_PointCloudShape (TopoDS_Shape(), theTol) {}
|
|
||||||
void SetPointArray (const Handle(Graphic3d_ArrayOfPoints)& thePoints) { myPoints = thePoints; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void addPoint (const gp_Pnt& thePoint,
|
|
||||||
const gp_Vec& theNorm,
|
|
||||||
const gp_Pnt2d& theUV,
|
|
||||||
const TopoDS_Shape& ) Standard_OVERRIDE
|
|
||||||
{
|
|
||||||
const Standard_Integer aPntIndex = myPoints->AddVertex (thePoint, theUV);
|
|
||||||
if (theNorm.SquareMagnitude() > gp::Resolution())
|
|
||||||
{
|
|
||||||
myPoints->SetVertexNormal (aPntIndex, theNorm);
|
|
||||||
}
|
|
||||||
if (myPoints->HasVertexColors())
|
|
||||||
{
|
|
||||||
Quantity_Color aColor (360.0 * Standard_Real(aPntIndex) / Standard_Real(myPoints->VertexNumberAllocated()),
|
|
||||||
1.0, 0.5, Quantity_TOC_HLS);
|
|
||||||
myPoints->SetVertexColor (aPntIndex, aColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Handle(Graphic3d_ArrayOfPoints) myPoints;
|
|
||||||
};
|
|
||||||
|
|
||||||
PointCloudPntFiller aPoitCloudTool (aTol);
|
|
||||||
aPoitCloudTool.SetShape (aShape);
|
|
||||||
aPoitCloudTool.SetDistance (aDist);
|
|
||||||
|
|
||||||
Standard_Integer aNbPoints = isDensityPoints
|
|
||||||
? aPoitCloudTool.NbPointsByDensity (aDensity)
|
|
||||||
: aPoitCloudTool.NbPointsByTriangulation();
|
|
||||||
theDI << "Number of the generated points : " << aNbPoints << "\n";
|
|
||||||
anArrayPoints = new Graphic3d_ArrayOfPoints (aNbPoints, aFlags);
|
|
||||||
aPoitCloudTool.SetPointArray (anArrayPoints);
|
|
||||||
Standard_Boolean isDone = isDensityPoints
|
|
||||||
? aPoitCloudTool.GeneratePointsByDensity (aDensity)
|
|
||||||
: aPoitCloudTool.GeneratePointsByTriangulation();
|
|
||||||
if (!isDone)
|
|
||||||
{
|
|
||||||
Message::SendFail() << "Error: Point cloud was not generated";
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (!aDistribution.IsEmpty())
|
|
||||||
{
|
|
||||||
const bool isSurface = aDistribution == "-surface";
|
|
||||||
|
|
||||||
anArrayPoints = new Graphic3d_ArrayOfPoints (aDistNbPoints, aFlags);
|
// calculate number of points
|
||||||
std::mt19937 aRandomGenerator(0);
|
TopLoc_Location aLocation;
|
||||||
std::uniform_real_distribution<> anAlphaDistrib(0.0, 2.0 * M_PI);
|
Standard_Integer aNbPoints = 0;
|
||||||
std::uniform_real_distribution<> aBetaDistrib (0.0, 2.0 * M_PI);
|
for (TopExp_Explorer aFaceIt (aShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
|
||||||
std::uniform_real_distribution<> aRadiusDistrib(0.0, aDistRadius);
|
|
||||||
for (Standard_Integer aPntIt = 0; aPntIt < aDistNbPoints; ++aPntIt)
|
|
||||||
{
|
{
|
||||||
Standard_Real anAlpha = anAlphaDistrib(aRandomGenerator);
|
const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current());
|
||||||
Standard_Real aBeta = aBetaDistrib (aRandomGenerator);
|
Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aLocation);
|
||||||
Standard_Real aDistance = isSurface ? aDistRadius : aRadiusDistrib (aRandomGenerator);
|
if (!aTriangulation.IsNull())
|
||||||
|
{
|
||||||
|
aNbPoints += aTriangulation->NbNodes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (aNbPoints < 3)
|
||||||
|
{
|
||||||
|
Message::SendFail ("Error: shape should be triangulated");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
anArrayPoints = new Graphic3d_ArrayOfPoints (aNbPoints, aFlags);
|
||||||
|
for (TopExp_Explorer aFaceIt (aShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
|
||||||
|
{
|
||||||
|
const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current());
|
||||||
|
Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aLocation);
|
||||||
|
if (aTriangulation.IsNull())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gp_Trsf& aTrsf = aLocation.Transformation();
|
||||||
|
|
||||||
|
// extract normals from nodes
|
||||||
|
TColgp_Array1OfDir aNormals (1, hasNormals ? aTriangulation->NbNodes() : 1);
|
||||||
|
if (hasNormals)
|
||||||
|
{
|
||||||
|
Poly_Connect aPolyConnect (aTriangulation);
|
||||||
|
StdPrs_ToolTriangulatedShape::Normal (aFace, aPolyConnect, aNormals);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter)
|
||||||
|
{
|
||||||
|
gp_Pnt aPoint = aTriangulation->Node (aNodeIter);
|
||||||
|
if (!aLocation.IsIdentity())
|
||||||
|
{
|
||||||
|
aPoint.Transform (aTrsf);
|
||||||
|
if (hasNormals)
|
||||||
|
{
|
||||||
|
aNormals (aNodeIter).Transform (aTrsf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add vertex into array of points
|
||||||
|
const Standard_Integer anIndexOfPoint = anArrayPoints->AddVertex (aPoint);
|
||||||
|
if (toRandColors)
|
||||||
|
{
|
||||||
|
Quantity_Color aColor (360.0 * Standard_Real(anIndexOfPoint) / Standard_Real(aNbPoints),
|
||||||
|
1.0, 0.5, Quantity_TOC_HLS);
|
||||||
|
anArrayPoints->SetVertexColor (anIndexOfPoint, aColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasNormals)
|
||||||
|
{
|
||||||
|
anArrayPoints->SetVertexNormal (anIndexOfPoint, aNormals (aNodeIter));
|
||||||
|
}
|
||||||
|
if (hasUV
|
||||||
|
&& aTriangulation->HasUVNodes())
|
||||||
|
{
|
||||||
|
anArrayPoints->SetVertexTexel (anIndexOfPoint, aTriangulation->UVNode (aNodeIter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (aCmd == CloudSphere)
|
||||||
|
{
|
||||||
|
Standard_Real aCenterX = Draw::Atof (theArgs[2]);
|
||||||
|
Standard_Real aCenterY = Draw::Atof (theArgs[3]);
|
||||||
|
Standard_Real aCenterZ = Draw::Atof (theArgs[4]);
|
||||||
|
Standard_Real aRadius = Draw::Atof (theArgs[5]);
|
||||||
|
Standard_Integer aNbPoints = Draw::Atoi (theArgs[6]);
|
||||||
|
|
||||||
|
TCollection_AsciiString aDistribution = TCollection_AsciiString(theArgs[7]);
|
||||||
|
aDistribution.LowerCase();
|
||||||
|
if ( aDistribution != "surface" && aDistribution != "volume" )
|
||||||
|
{
|
||||||
|
Message::SendFail ("Syntax error: wrong arguments. See usage:");
|
||||||
|
theDI.PrintHelp (theArgs[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
Standard_Boolean isSurface = aDistribution == "surface";
|
||||||
|
|
||||||
|
gp_Pnt aCenter(aCenterX, aCenterY, aCenterZ);
|
||||||
|
|
||||||
|
anArrayPoints = new Graphic3d_ArrayOfPoints (aNbPoints, aFlags);
|
||||||
|
for (Standard_Integer aPntIt = 0; aPntIt < aNbPoints; ++aPntIt)
|
||||||
|
{
|
||||||
|
Standard_Real anAlpha = (Standard_Real (rand() % 2000) / 1000.0) * M_PI;
|
||||||
|
Standard_Real aBeta = (Standard_Real (rand() % 2000) / 1000.0) * M_PI;
|
||||||
|
Standard_Real aDistance = isSurface ?
|
||||||
|
aRadius : (Standard_Real (rand() % aNbPoints) / aNbPoints) * aRadius;
|
||||||
|
|
||||||
gp_Dir aDir (Cos (anAlpha) * Sin (aBeta),
|
gp_Dir aDir (Cos (anAlpha) * Sin (aBeta),
|
||||||
Sin (anAlpha),
|
Sin (anAlpha),
|
||||||
Cos (anAlpha) * Cos (aBeta));
|
Cos (anAlpha) * Cos (aBeta));
|
||||||
gp_Pnt aPoint = aDistCenter.Translated (aDir.XYZ() * aDistance);
|
gp_Pnt aPoint = aCenter.Translated (aDir.XYZ() * aDistance);
|
||||||
|
|
||||||
const Standard_Integer anIndexOfPoint = anArrayPoints->AddVertex (aPoint);
|
const Standard_Integer anIndexOfPoint = anArrayPoints->AddVertex (aPoint);
|
||||||
if (toRandColors)
|
if (toRandColors)
|
||||||
{
|
{
|
||||||
Quantity_Color aColor (360.0 * Standard_Real (anIndexOfPoint) / Standard_Real (aDistNbPoints),
|
Quantity_Color aColor (360.0 * Standard_Real (anIndexOfPoint) / Standard_Real (aNbPoints),
|
||||||
1.0, 0.5, Quantity_TOC_HLS);
|
1.0, 0.5, Quantity_TOC_HLS);
|
||||||
anArrayPoints->SetVertexColor (anIndexOfPoint, aColor);
|
anArrayPoints->SetVertexColor (anIndexOfPoint, aColor);
|
||||||
}
|
}
|
||||||
@@ -6477,16 +6484,11 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Message::SendFail ("Error: wrong number of arguments");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set array of points in point cloud object
|
// set array of points in point cloud object
|
||||||
Handle(AIS_PointCloud) aPointCloud = new AIS_PointCloud();
|
Handle(AIS_PointCloud) aPointCloud = new AIS_PointCloud();
|
||||||
aPointCloud->SetPoints (anArrayPoints);
|
aPointCloud->SetPoints (anArrayPoints);
|
||||||
ViewerTest::Display (aName, aPointCloud);
|
VDisplayAISObject (aName, aPointCloud);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7147,23 +7149,18 @@ Prints the default vertex draw mode without -set parameter.
|
|||||||
)" /* [vvertexmode] */);
|
)" /* [vvertexmode] */);
|
||||||
|
|
||||||
addCmd ("vpointcloud", VPointCloud, /* [vpointcloud] */ R"(
|
addCmd ("vpointcloud", VPointCloud, /* [vpointcloud] */ R"(
|
||||||
vpointcloud name shape [-randColor {0|1}]=0 [-normals {0|1}]=1 [-uv {0|1}]=0
|
vpointcloud name shape [-randColor] [-normals] [-noNormals] [-uv]
|
||||||
[-distance Value]=0.0 [-density Value] [-tolerance Value]
|
|
||||||
Create an interactive object for arbitrary set of points from triangulated shape.
|
Create an interactive object for arbitrary set of points from triangulated shape.
|
||||||
|
|
||||||
vpointcloud name {-surface|-volume} x y z r npts
|
vpointcloud name x y z r npts {surface|volume}
|
||||||
[-randColor] [-normals] [-uv]
|
... [-randColor] [-normals] [-noNormals] [-uv]
|
||||||
Create arbitrary set of points (npts) randomly distributed
|
Create arbitrary set of points (npts) randomly distributed
|
||||||
on spheric surface or within spheric volume (x y z r).
|
on spheric surface or within spheric volume (x y z r).
|
||||||
|
|
||||||
Additional options:
|
Additional options:
|
||||||
-normals generate or not normal per point
|
-randColor - generate random color per point
|
||||||
-uv generate UV (texel) coordinates per point
|
-normals - generate normal per point (default)
|
||||||
-randColor generate random color per point
|
-noNormals - do not generate normal per point
|
||||||
-distance distance from shape into the range [0, Value];
|
|
||||||
-density density of points to generate randomly on surface;
|
|
||||||
-tolerance cloud generator's tolerance; default value is Precision::Confusion();
|
|
||||||
|
|
||||||
)" /* [vpointcloud] */);
|
)" /* [vpointcloud] */);
|
||||||
|
|
||||||
addCmd ("vpriority", VPriority, /* [vpriority] */ R"(
|
addCmd ("vpriority", VPriority, /* [vpriority] */ R"(
|
||||||
|
@@ -19,7 +19,6 @@
|
|||||||
#include <Aspect_TypeOfMarker.hxx>
|
#include <Aspect_TypeOfMarker.hxx>
|
||||||
#include <Bnd_Box.hxx>
|
#include <Bnd_Box.hxx>
|
||||||
#include <BRep_Builder.hxx>
|
#include <BRep_Builder.hxx>
|
||||||
#include <BRepLib_PointCloudShape.hxx>
|
|
||||||
#include <DBRep.hxx>
|
#include <DBRep.hxx>
|
||||||
#include <DDocStd.hxx>
|
#include <DDocStd.hxx>
|
||||||
#include <DDocStd_DrawDocument.hxx>
|
#include <DDocStd_DrawDocument.hxx>
|
||||||
@@ -46,13 +45,10 @@
|
|||||||
#include <Quantity_NameOfColor.hxx>
|
#include <Quantity_NameOfColor.hxx>
|
||||||
#include <RWGltf_CafReader.hxx>
|
#include <RWGltf_CafReader.hxx>
|
||||||
#include <RWGltf_CafWriter.hxx>
|
#include <RWGltf_CafWriter.hxx>
|
||||||
#include <RWMesh_FaceIterator.hxx>
|
|
||||||
#include <RWStl.hxx>
|
#include <RWStl.hxx>
|
||||||
#include <RWObj.hxx>
|
#include <RWObj.hxx>
|
||||||
#include <RWObj_CafReader.hxx>
|
#include <RWObj_CafReader.hxx>
|
||||||
#include <RWObj_CafWriter.hxx>
|
#include <RWObj_CafWriter.hxx>
|
||||||
#include <RWPly_CafWriter.hxx>
|
|
||||||
#include <RWPly_PlyWriterContext.hxx>
|
|
||||||
#include <SelectMgr_SelectionManager.hxx>
|
#include <SelectMgr_SelectionManager.hxx>
|
||||||
#include <Standard_ErrorHandler.hxx>
|
#include <Standard_ErrorHandler.hxx>
|
||||||
#include <StdSelect_ViewerSelector3d.hxx>
|
#include <StdSelect_ViewerSelector3d.hxx>
|
||||||
@@ -66,7 +62,6 @@
|
|||||||
#include <TDataStd_Name.hxx>
|
#include <TDataStd_Name.hxx>
|
||||||
#include <TDocStd_Application.hxx>
|
#include <TDocStd_Application.hxx>
|
||||||
#include <TDocStd_Document.hxx>
|
#include <TDocStd_Document.hxx>
|
||||||
#include <TopoDS.hxx>
|
|
||||||
#include <TopoDS_Face.hxx>
|
#include <TopoDS_Face.hxx>
|
||||||
#include <TopoDS_Shape.hxx>
|
#include <TopoDS_Shape.hxx>
|
||||||
#include <UnitsAPI.hxx>
|
#include <UnitsAPI.hxx>
|
||||||
@@ -80,7 +75,6 @@
|
|||||||
#include <VrmlData_ShapeConvert.hxx>
|
#include <VrmlData_ShapeConvert.hxx>
|
||||||
#include <XCAFDoc_DocumentTool.hxx>
|
#include <XCAFDoc_DocumentTool.hxx>
|
||||||
#include <XCAFDoc_ShapeTool.hxx>
|
#include <XCAFDoc_ShapeTool.hxx>
|
||||||
#include <XCAFPrs_DocumentExplorer.hxx>
|
|
||||||
#include <XSAlgo.hxx>
|
#include <XSAlgo.hxx>
|
||||||
#include <XSAlgo_AlgoContainer.hxx>
|
#include <XSAlgo_AlgoContainer.hxx>
|
||||||
#include <XSDRAW.hxx>
|
#include <XSDRAW.hxx>
|
||||||
@@ -2061,275 +2055,6 @@ static Standard_Integer meshinfo(Draw_Interpretor& di,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : writeply
|
|
||||||
//purpose : write PLY file
|
|
||||||
//=======================================================================
|
|
||||||
static Standard_Integer WritePly (Draw_Interpretor& theDI,
|
|
||||||
Standard_Integer theNbArgs,
|
|
||||||
const char** theArgVec)
|
|
||||||
{
|
|
||||||
Handle(TDocStd_Document) aDoc;
|
|
||||||
Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
|
|
||||||
TCollection_AsciiString aShapeName, aFileName;
|
|
||||||
|
|
||||||
Standard_Real aDist = 0.0;
|
|
||||||
Standard_Real aDens = Precision::Infinite();
|
|
||||||
Standard_Real aTol = Precision::Confusion();
|
|
||||||
bool hasColors = true, hasNormals = true, hasTexCoords = false, hasPartId = true, hasFaceId = false;
|
|
||||||
bool isPntSet = false, isDensityPoints = false;
|
|
||||||
TColStd_IndexedDataMapOfStringString aFileInfo;
|
|
||||||
for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
|
|
||||||
{
|
|
||||||
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
||||||
anArg.LowerCase();
|
|
||||||
if (anArg == "-normal")
|
|
||||||
{
|
|
||||||
hasNormals = Draw::ParseOnOffIterator (theNbArgs, theArgVec, anArgIter);
|
|
||||||
}
|
|
||||||
else if (anArg == "-nonormal")
|
|
||||||
{
|
|
||||||
hasNormals = !Draw::ParseOnOffIterator (theNbArgs, theArgVec, anArgIter);
|
|
||||||
}
|
|
||||||
else if (anArg == "-color"
|
|
||||||
|| anArg == "-nocolor"
|
|
||||||
|| anArg == "-colors"
|
|
||||||
|| anArg == "-nocolors")
|
|
||||||
{
|
|
||||||
hasColors = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
|
|
||||||
}
|
|
||||||
else if (anArg == "-uv"
|
|
||||||
|| anArg == "-nouv")
|
|
||||||
{
|
|
||||||
hasTexCoords = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
|
|
||||||
}
|
|
||||||
else if (anArg == "-partid")
|
|
||||||
{
|
|
||||||
hasPartId = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
|
|
||||||
hasFaceId = hasFaceId && !hasPartId;
|
|
||||||
}
|
|
||||||
else if (anArg == "-surfid"
|
|
||||||
|| anArg == "-surfaceid"
|
|
||||||
|| anArg == "-faceid")
|
|
||||||
{
|
|
||||||
hasFaceId = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
|
|
||||||
hasPartId = hasPartId && !hasFaceId;
|
|
||||||
}
|
|
||||||
else if (anArg == "-pntset"
|
|
||||||
|| anArg == "-pntcloud"
|
|
||||||
|| anArg == "-pointset"
|
|
||||||
|| anArg == "-pointcloud"
|
|
||||||
|| anArg == "-cloud"
|
|
||||||
|| anArg == "-points")
|
|
||||||
{
|
|
||||||
isPntSet = Draw::ParseOnOffIterator (theNbArgs, theArgVec, anArgIter);
|
|
||||||
}
|
|
||||||
else if ((anArg == "-dist"
|
|
||||||
|| anArg == "-distance")
|
|
||||||
&& anArgIter + 1 < theNbArgs
|
|
||||||
&& Draw::ParseReal (theArgVec[anArgIter + 1], aDist))
|
|
||||||
{
|
|
||||||
++anArgIter;
|
|
||||||
isPntSet = true;
|
|
||||||
if (aDist < 0.0)
|
|
||||||
{
|
|
||||||
theDI << "Syntax error: -distance value should be >= 0.0";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
aDist = Max (aDist, Precision::Confusion());
|
|
||||||
}
|
|
||||||
else if ((anArg == "-dens"
|
|
||||||
|| anArg == "-density")
|
|
||||||
&& anArgIter + 1 < theNbArgs
|
|
||||||
&& Draw::ParseReal (theArgVec[anArgIter + 1], aDens))
|
|
||||||
{
|
|
||||||
++anArgIter;
|
|
||||||
isDensityPoints = Standard_True;
|
|
||||||
isPntSet = true;
|
|
||||||
if (aDens <= 0.0)
|
|
||||||
{
|
|
||||||
theDI << "Syntax error: -density value should be > 0.0";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((anArg == "-tol"
|
|
||||||
|| anArg == "-tolerance")
|
|
||||||
&& anArgIter + 1 < theNbArgs
|
|
||||||
&& Draw::ParseReal (theArgVec[anArgIter + 1], aTol))
|
|
||||||
{
|
|
||||||
++anArgIter;
|
|
||||||
isPntSet = true;
|
|
||||||
if (aTol < Precision::Confusion())
|
|
||||||
{
|
|
||||||
theDI << "Syntax error: -tol value should be >= " << Precision::Confusion();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (anArg == "-comments"
|
|
||||||
&& anArgIter + 1 < theNbArgs)
|
|
||||||
{
|
|
||||||
aFileInfo.Add ("Comments", theArgVec[++anArgIter]);
|
|
||||||
}
|
|
||||||
else if (anArg == "-author"
|
|
||||||
&& anArgIter + 1 < theNbArgs)
|
|
||||||
{
|
|
||||||
aFileInfo.Add ("Author", theArgVec[++anArgIter]);
|
|
||||||
}
|
|
||||||
else if (aDoc.IsNull())
|
|
||||||
{
|
|
||||||
if (aShapeName.IsEmpty())
|
|
||||||
{
|
|
||||||
aShapeName = theArgVec[anArgIter];
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_CString aNameVar = theArgVec[anArgIter];
|
|
||||||
DDocStd::GetDocument (aNameVar, aDoc, false);
|
|
||||||
if (aDoc.IsNull())
|
|
||||||
{
|
|
||||||
TopoDS_Shape aShape = DBRep::Get (aNameVar);
|
|
||||||
if (!aShape.IsNull())
|
|
||||||
{
|
|
||||||
anApp->NewDocument (TCollection_ExtendedString ("BinXCAF"), aDoc);
|
|
||||||
Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (aDoc->Main());
|
|
||||||
aShapeTool->AddShape (aShape);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (aFileName.IsEmpty())
|
|
||||||
{
|
|
||||||
aFileName = theArgVec[anArgIter];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (aDoc.IsNull()
|
|
||||||
&& !aShapeName.IsEmpty())
|
|
||||||
{
|
|
||||||
theDI << "Syntax error: '" << aShapeName << "' is not a shape nor document";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (aDoc.IsNull()
|
|
||||||
|| aFileName.IsEmpty())
|
|
||||||
{
|
|
||||||
theDI << "Syntax error: wrong number of arguments";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
TDF_LabelSequence aRootLabels;
|
|
||||||
Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (aDoc->Main());
|
|
||||||
aShapeTool->GetFreeShapes (aRootLabels);
|
|
||||||
if (aRootLabels.IsEmpty())
|
|
||||||
{
|
|
||||||
theDI << "Error: empty document";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isPntSet)
|
|
||||||
{
|
|
||||||
class PointCloudPlyWriter : public BRepLib_PointCloudShape, public RWPly_PlyWriterContext
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PointCloudPlyWriter (Standard_Real theTol)
|
|
||||||
: BRepLib_PointCloudShape (TopoDS_Shape(), theTol) {}
|
|
||||||
|
|
||||||
void AddFaceColor (const TopoDS_Shape& theFace, const Graphic3d_Vec4ub& theColor)
|
|
||||||
{ myFaceColor.Bind (theFace, theColor); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void addPoint (const gp_Pnt& thePoint,
|
|
||||||
const gp_Vec& theNorm,
|
|
||||||
const gp_Pnt2d& theUV,
|
|
||||||
const TopoDS_Shape& theFace)
|
|
||||||
{
|
|
||||||
Graphic3d_Vec4ub aColor;
|
|
||||||
myFaceColor.Find (theFace, aColor);
|
|
||||||
RWPly_PlyWriterContext::WriteVertex (thePoint,
|
|
||||||
Graphic3d_Vec3 ((float )theNorm.X(), (float )theNorm.Y(), (float )theNorm.Z()),
|
|
||||||
Graphic3d_Vec2 ((float )theUV.X(), (float )theUV.Y()),
|
|
||||||
aColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
NCollection_DataMap<TopoDS_Shape, Graphic3d_Vec4ub> myFaceColor;
|
|
||||||
};
|
|
||||||
|
|
||||||
PointCloudPlyWriter aPlyCtx (aTol);
|
|
||||||
aPlyCtx.SetNormals (hasNormals);
|
|
||||||
aPlyCtx.SetColors (hasColors);
|
|
||||||
aPlyCtx.SetTexCoords (hasTexCoords);
|
|
||||||
|
|
||||||
TopoDS_Compound aComp;
|
|
||||||
BRep_Builder().MakeCompound (aComp);
|
|
||||||
for (XCAFPrs_DocumentExplorer aDocExplorer (aDoc, aRootLabels, XCAFPrs_DocumentExplorerFlags_OnlyLeafNodes);
|
|
||||||
aDocExplorer.More(); aDocExplorer.Next())
|
|
||||||
{
|
|
||||||
const XCAFPrs_DocumentNode& aDocNode = aDocExplorer.Current();
|
|
||||||
for (RWMesh_FaceIterator aFaceIter (aDocNode.RefLabel, aDocNode.Location, true, aDocNode.Style); aFaceIter.More(); aFaceIter.Next())
|
|
||||||
{
|
|
||||||
BRep_Builder().Add (aComp, aFaceIter.Face());
|
|
||||||
Graphic3d_Vec4ub aColorVec (255);
|
|
||||||
if (aFaceIter.HasFaceColor())
|
|
||||||
{
|
|
||||||
Graphic3d_Vec4 aColorF = aFaceIter.FaceColor();
|
|
||||||
aColorVec.SetValues ((unsigned char )int(aColorF.r() * 255.0f),
|
|
||||||
(unsigned char )int(aColorF.g() * 255.0f),
|
|
||||||
(unsigned char )int(aColorF.b() * 255.0f),
|
|
||||||
(unsigned char )int(aColorF.a() * 255.0f));
|
|
||||||
}
|
|
||||||
aPlyCtx.AddFaceColor (aFaceIter.Face(), aColorVec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
aPlyCtx.SetShape (aComp);
|
|
||||||
|
|
||||||
Standard_Integer aNbPoints = isDensityPoints
|
|
||||||
? aPlyCtx.NbPointsByDensity (aDens)
|
|
||||||
: aPlyCtx.NbPointsByTriangulation();
|
|
||||||
if (aNbPoints <= 0)
|
|
||||||
{
|
|
||||||
theDI << "Error: unable to generate points";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!aPlyCtx.Open (aFileName)
|
|
||||||
|| !aPlyCtx.WriteHeader (aNbPoints, 0, TColStd_IndexedDataMapOfStringString()))
|
|
||||||
{
|
|
||||||
theDI << "Error: unable to create file '" << aFileName << "'";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Boolean isDone = isDensityPoints
|
|
||||||
? aPlyCtx.GeneratePointsByDensity (aDens)
|
|
||||||
: aPlyCtx.GeneratePointsByTriangulation();
|
|
||||||
if (!isDone)
|
|
||||||
{
|
|
||||||
theDI << "Error: Point cloud was not generated in file '" << aFileName << "'";
|
|
||||||
}
|
|
||||||
else if (!aPlyCtx.Close())
|
|
||||||
{
|
|
||||||
theDI << "Error: Point cloud file '" << aFileName << "' was not written";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
theDI << aNbPoints;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
|
|
||||||
RWPly_CafWriter aPlyCtx (aFileName);
|
|
||||||
aPlyCtx.SetNormals (hasNormals);
|
|
||||||
aPlyCtx.SetColors (hasColors);
|
|
||||||
aPlyCtx.SetTexCoords (hasTexCoords);
|
|
||||||
aPlyCtx.SetPartId (hasPartId);
|
|
||||||
aPlyCtx.SetFaceId (hasFaceId);
|
|
||||||
aPlyCtx.Perform (aDoc, aFileInfo, aProgress->Start());
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
|
void XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
|
||||||
@@ -2435,25 +2160,6 @@ void XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
|
|||||||
theCommands.Add ("meshdeform", "display deformed mesh", __FILE__, meshdeform, g );
|
theCommands.Add ("meshdeform", "display deformed mesh", __FILE__, meshdeform, g );
|
||||||
theCommands.Add ("mesh_edge_width", "set width of edges", __FILE__, mesh_edge_width, g );
|
theCommands.Add ("mesh_edge_width", "set width of edges", __FILE__, mesh_edge_width, g );
|
||||||
theCommands.Add ("meshinfo", "displays the number of nodes and triangles", __FILE__, meshinfo, g );
|
theCommands.Add ("meshinfo", "displays the number of nodes and triangles", __FILE__, meshinfo, g );
|
||||||
theCommands.Add ("WritePly", R"(
|
|
||||||
WritePly Doc file [-normals {0|1}]=1 [-colors {0|1}]=1 [-uv {0|1}]=0 [-partId {0|1}]=1 [-faceId {0|1}]=0
|
|
||||||
[-pointCloud {0|1}]=0 [-distance Value]=0.0 [-density Value] [-tolerance Value]
|
|
||||||
Write document or triangulated shape into PLY file.
|
|
||||||
-normals write per-vertex normals
|
|
||||||
-colors write per-vertex colors
|
|
||||||
-uv write per-vertex UV coordinates
|
|
||||||
-partId write per-element part index (alternative to -faceId)
|
|
||||||
-faceId write per-element face index (alternative to -partId)
|
|
||||||
|
|
||||||
Generate point cloud out of the shape and write it into PLY file.
|
|
||||||
-pointCloud write point cloud instead without triangulation indices
|
|
||||||
-distance sets distance from shape into the range [0, Value];
|
|
||||||
-density sets density of points to generate randomly on surface;
|
|
||||||
-tolerance sets tolerance; default value is Precision::Confusion();
|
|
||||||
)", __FILE__, WritePly, g);
|
|
||||||
theCommands.Add ("writeply",
|
|
||||||
"writeply shape file",
|
|
||||||
__FILE__, WritePly, g);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
@@ -1,9 +0,0 @@
|
|||||||
puts "================"
|
|
||||||
puts "0032767: Mesh - incorrect splitting of edges of seams leading to hang \[since OCCT 7.4.0\] "
|
|
||||||
puts "================"
|
|
||||||
puts ""
|
|
||||||
|
|
||||||
restore [locate_data_file bug32767.brep] s
|
|
||||||
tclean s
|
|
||||||
incmesh s 0.01
|
|
||||||
checktrinfo s -tri 3220 -nod 1770 -defl 0.018398669654253779 -tol_abs_defl 1e-6
|
|
@@ -1,17 +0,0 @@
|
|||||||
puts "======="
|
|
||||||
puts "0032731: Data Exchange, Step Import - Incorrect PMI text location"
|
|
||||||
puts "======="
|
|
||||||
|
|
||||||
pload OCAF
|
|
||||||
|
|
||||||
Close D -silent
|
|
||||||
|
|
||||||
# Read file
|
|
||||||
ReadStep D [locate_data_file bug32731_A5E46910589A.stp]
|
|
||||||
|
|
||||||
#Checking
|
|
||||||
XGetShape repr0 D 0:1:4:106:16
|
|
||||||
checkgravitycenter repr0 -l -109.847 153.679 0 1e-7
|
|
||||||
|
|
||||||
XGetShape repr1 D 0:1:4:56:16
|
|
||||||
checkgravitycenter repr1 -l -68.7 123.272 -18.5624 1e-7
|
|
@@ -5,4 +5,3 @@
|
|||||||
005 gltf_lateload
|
005 gltf_lateload
|
||||||
006 obj_read
|
006 obj_read
|
||||||
007 obj_write
|
007 obj_write
|
||||||
008 ply_write
|
|
||||||
|
@@ -1,14 +0,0 @@
|
|||||||
puts "============"
|
|
||||||
puts "0029325: Modeling Algorithms - add tool BRepLib_PointCloudShape for generation point cloud for specified shape"
|
|
||||||
puts "============"
|
|
||||||
puts ""
|
|
||||||
|
|
||||||
pload XDE OCAF MODELING VISUALIZATION
|
|
||||||
|
|
||||||
set aNbPntsExpected 32581
|
|
||||||
set aTmpPly ${imagedir}/${casename}_tmp.ply
|
|
||||||
lappend occ_tmp_files $aTmpPly
|
|
||||||
|
|
||||||
restore [locate_data_file bug29325_EQUERRE.brep] aShape
|
|
||||||
set aNbPnts [writeply aShape $aTmpPly -pointCloud -dist 0.0 -dens 0.1 -colors 0]
|
|
||||||
if {$aNbPnts != $aNbPntsExpected} { puts "Error: ($aNbPnts) generated while expected ($aNbPntsExpected)" }
|
|
@@ -1,14 +0,0 @@
|
|||||||
puts "============"
|
|
||||||
puts "0029325: Modeling Algorithms - add tool BRepLib_PointCloudShape for generation point cloud for specified shape"
|
|
||||||
puts "============"
|
|
||||||
puts ""
|
|
||||||
|
|
||||||
pload XDE OCAF MODELING VISUALIZATION
|
|
||||||
|
|
||||||
set aNbPntsExpected 27890
|
|
||||||
set aTmpPly ${imagedir}/${casename}_tmp.ply
|
|
||||||
lappend occ_tmp_files $aTmpPly
|
|
||||||
|
|
||||||
restore [locate_data_file bug29325_SANGLE_DE_FIXATION.brep] aShape
|
|
||||||
set aNbPnts [writeply aShape $aTmpPly -pointCloud -dist 0.0 -dens 0.5 -colors 0]
|
|
||||||
if {$aNbPnts != $aNbPntsExpected} { puts "Error: ($aNbPnts) generated while expected ($aNbPntsExpected)" }
|
|
16
tests/pipe/bugs/bug32811
Normal file
16
tests/pipe/bugs/bug32811
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
puts "TODO ? Surface Surface Intersect Lost One Intersect Curve"
|
||||||
|
puts "0032811: Bad result of sweep operation due to Surface Surface Intersect Bug"
|
||||||
|
puts "========"
|
||||||
|
puts ""
|
||||||
|
|
||||||
|
restore [locate_data_file CR32811_path.brep] p
|
||||||
|
restore [locate_data_file CR32811_profile.brep] pr
|
||||||
|
|
||||||
|
mksweep p
|
||||||
|
setsweep -CF
|
||||||
|
addsweep pr
|
||||||
|
|
||||||
|
buildsweep result -C -S
|
||||||
|
|
||||||
|
checkshape result
|
||||||
|
checknbshapes result -vertex 184 -edge 368 -wire 184 -face 184 -shell 1
|
@@ -21,7 +21,7 @@ vrotate 0.2 0.0 0.0
|
|||||||
vdump $::imagedir/${::casename}_green.png
|
vdump $::imagedir/${::casename}_green.png
|
||||||
|
|
||||||
# random colors mode
|
# random colors mode
|
||||||
vpointcloud p s -randcolors -nonormals
|
vpointcloud p s -randcolors
|
||||||
vdump $::imagedir/${::casename}_rand.png
|
vdump $::imagedir/${::casename}_rand.png
|
||||||
|
|
||||||
# texture mapping
|
# texture mapping
|
||||||
|
Reference in New Issue
Block a user