1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-16 10:08:36 +03:00
occt/src/RWMesh/RWMesh_FaceIterator.cxx
kgv 35ad04e78b 0032107: Data Exchange, RWGltf_CafReader - reading glTF document back loses sharing
RWGltf_CafWriter has been fixed to write shared Faces having a different style.
RWGltf_GltfJsonParser::gltfParsePrimArray() now tries to create a shared TopoDS_Face
from the same primitive array definition.

RWGltf_CafReader - improved name generation.
2021-09-10 20:22:59 +03:00

250 lines
7.1 KiB
C++

// Copyright (c) 2017-2019 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 <RWMesh_FaceIterator.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRep_Tool.hxx>
#include <TopExp.hxx>
#include <TopoDS.hxx>
#include <XCAFDoc_ShapeTool.hxx>
#include <XCAFPrs.hxx>
// =======================================================================
// function : RWMesh_FaceIterator
// purpose :
// =======================================================================
RWMesh_FaceIterator::RWMesh_FaceIterator (const TDF_Label& theLabel,
const TopLoc_Location& theLocation,
const Standard_Boolean theToMapColors,
const XCAFPrs_Style& theStyle)
: myDefStyle (theStyle),
myToMapColors (theToMapColors),
mySLTool (1, 1e-12),
myHasNormals (false),
myIsMirrored (false),
myHasFaceColor (false)
{
TopoDS_Shape aShape;
if (!XCAFDoc_ShapeTool::GetShape (theLabel, aShape)
|| aShape.IsNull())
{
return;
}
aShape.Location (theLocation, false);
myFaceIter.Init (aShape, TopAbs_FACE);
if (theToMapColors)
{
dispatchStyles (theLabel, theLocation, theStyle);
myStyles.Bind (aShape, theStyle);
}
Next();
}
// =======================================================================
// function : RWMesh_FaceIterator
// purpose :
// =======================================================================
RWMesh_FaceIterator::RWMesh_FaceIterator (const TopoDS_Shape& theShape,
const XCAFPrs_Style& theStyle)
: myDefStyle (theStyle),
myToMapColors (true),
mySLTool (1, 1e-12),
myHasNormals (false),
myIsMirrored (false),
myHasFaceColor (false)
{
if (theShape.IsNull())
{
return;
}
myFaceIter.Init (theShape, TopAbs_FACE);
Next();
}
// =======================================================================
// function : dispatchStyles
// purpose :
// =======================================================================
void RWMesh_FaceIterator::dispatchStyles (const TDF_Label& theLabel,
const TopLoc_Location& theLocation,
const XCAFPrs_Style& theStyle)
{
TopLoc_Location aDummyLoc;
XCAFPrs_IndexedDataMapOfShapeStyle aStyles;
XCAFPrs::CollectStyleSettings (theLabel, aDummyLoc, aStyles);
Standard_Integer aNbTypes[TopAbs_SHAPE] = {};
for (Standard_Integer aTypeIter = TopAbs_FACE; aTypeIter >= TopAbs_COMPOUND; --aTypeIter)
{
if (aTypeIter != TopAbs_FACE
&& aNbTypes[aTypeIter] == 0)
{
continue;
}
for (XCAFPrs_IndexedDataMapOfShapeStyle::Iterator aStyleIter (aStyles); aStyleIter.More(); aStyleIter.Next())
{
const TopoDS_Shape& aKeyShape = aStyleIter.Key();
const TopAbs_ShapeEnum aKeyShapeType = aKeyShape.ShapeType();
if (aTypeIter == TopAbs_FACE)
{
++aNbTypes[aKeyShapeType];
}
if (aTypeIter != aKeyShapeType)
{
continue;
}
XCAFPrs_Style aCafStyle = aStyleIter.Value();
if (!aCafStyle.IsSetColorCurv()
&& theStyle.IsSetColorCurv())
{
aCafStyle.SetColorCurv (theStyle.GetColorCurv());
}
if (!aCafStyle.IsSetColorSurf()
&& theStyle.IsSetColorSurf())
{
aCafStyle.SetColorSurf (theStyle.GetColorSurfRGBA());
}
if (aCafStyle.Material().IsNull()
&& !theStyle.Material().IsNull())
{
aCafStyle.SetMaterial (theStyle.Material());
}
TopoDS_Shape aKeyShapeLocated = aKeyShape.Located (theLocation);
if (aKeyShapeType == TopAbs_FACE)
{
myStyles.Bind (aKeyShapeLocated, aCafStyle);
}
else
{
for (TopExp_Explorer aFaceIter (aKeyShapeLocated, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
{
if (!myStyles.IsBound (aFaceIter.Current()))
{
myStyles.Bind (aFaceIter.Current(), aCafStyle);
}
}
}
}
}
}
// =======================================================================
// function : normal
// purpose :
// =======================================================================
gp_Dir RWMesh_FaceIterator::normal (Standard_Integer theNode) const
{
gp_Dir aNormal (gp::DZ());
if (myPolyTriang->HasNormals())
{
Graphic3d_Vec3 aNormVec3;
myPolyTriang->Normal (theNode, aNormVec3);
if (aNormVec3.Modulus() != 0.0f)
{
aNormal.SetCoord (aNormVec3.x(), aNormVec3.y(), aNormVec3.z());
}
}
else if (myHasNormals
&& myPolyTriang->HasUVNodes())
{
const gp_XY anUV = myPolyTriang->UVNode (theNode).XY();
mySLTool.SetParameters (anUV.X(), anUV.Y());
if (mySLTool.IsNormalDefined())
{
aNormal = mySLTool.Normal();
}
}
return aNormal;
}
// =======================================================================
// function : Next
// purpose :
// =======================================================================
void RWMesh_FaceIterator::Next()
{
for (; myFaceIter.More(); myFaceIter.Next())
{
myFace = TopoDS::Face (myFaceIter.Current());
myPolyTriang = BRep_Tool::Triangulation (myFace, myFaceLocation);
myTrsf = myFaceLocation.Transformation();
if (myPolyTriang.IsNull()
|| myPolyTriang->NbTriangles() == 0)
{
resetFace();
continue;
}
initFace();
myFaceIter.Next();
return;
}
resetFace();
}
// =======================================================================
// function : initFace
// purpose :
// =======================================================================
void RWMesh_FaceIterator::initFace()
{
myHasNormals = false;
myHasFaceColor = false;
myIsMirrored = myTrsf.VectorialPart().Determinant() < 0.0;
if (myPolyTriang->HasNormals())
{
myHasNormals = true;
}
if (myPolyTriang->HasUVNodes() && !myHasNormals)
{
TopoDS_Face aFaceFwd = TopoDS::Face (myFace.Oriented (TopAbs_FORWARD));
aFaceFwd.Location (TopLoc_Location());
TopLoc_Location aLoc;
if (!BRep_Tool::Surface (aFaceFwd, aLoc).IsNull())
{
myFaceAdaptor.Initialize (aFaceFwd, false);
mySLTool.SetSurface (myFaceAdaptor);
myHasNormals = true;
}
}
if (!myToMapColors)
{
return;
}
if (!myStyles.Find (myFace, myFaceStyle))
{
myFaceStyle = myDefStyle;
}
if (!myFaceStyle.Material().IsNull())
{
myHasFaceColor = true;
myFaceColor = myFaceStyle.Material()->BaseColor();
}
else if (myFaceStyle.IsSetColorSurf())
{
myHasFaceColor = true;
myFaceColor = myFaceStyle.GetColorSurfRGBA();
}
}