1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-05-26 11:05:31 +03:00

Data Exchange, Step Export - Apply a scaling transformation (#513)

Add possibility to export scaling factor into the STEP file as a cartesian_transformation_operator_3d.
Add flag for turning on/off (on by default) this behavior.
This commit is contained in:
ikochetkova 2025-05-12 17:15:58 +01:00 committed by GitHub
parent 7cd39973a4
commit 18a46604fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 262 additions and 27 deletions

View File

@ -126,4 +126,4 @@ public:
// clang-format on
};
#endif // _DESTEP_Parameters_HeaderFile
#endif // _DEIGES_Parameters_HeaderFile

View File

@ -200,6 +200,8 @@ bool DESTEP_ConfigurationNode::Load(const Handle(DE_ConfigurationContext)& theRe
aScope);
InternalParameters.CleanDuplicates =
theResource->BooleanVal("write.cleanduplicates", InternalParameters.CleanDuplicates, aScope);
InternalParameters.WriteScalingTrsf =
theResource->BooleanVal("write.scaling.trsf", InternalParameters.WriteScalingTrsf, aScope);
return DE_ShapeFixConfigurationNode::Load(theResource);
}
@ -589,6 +591,13 @@ TCollection_AsciiString DESTEP_ConfigurationNode::Save() const
aResult += aScope + "write.cleanduplicates :\t " + InternalParameters.CleanDuplicates + "\n";
aResult += "!\n";
aResult += "!\n";
aResult +=
"!Defines export scaling factor in transformation as Cartesian Operator (On) or skip(Off)";
aResult += "!Default value: 1(\"On\"). Available values: 0(\"OFF\"), 1(\"On\")\n";
aResult += aScope + "write.scaling.trsf :\t " + InternalParameters.WriteScalingTrsf + "\n";
aResult += "!\n";
aResult += DE_ShapeFixConfigurationNode::Save();
aResult += "!*****************************************************************************\n";

View File

@ -203,6 +203,7 @@ public:
bool WriteVisMaterial = false; //<! VisMaterialMode is used to indicate write Visual Material or not
STEPControl_StepModelType WriteModelType = STEPControl_AsIs; //<! Gives you the choice of translation mode for an Open CASCADE shape that is being translated to STEP
bool CleanDuplicates = false; //<! Indicates whether to remove duplicate entities from the STEP file
bool WriteScalingTrsf = true; //<! Indicates if scaling should be written as Cartesian Operator or skipped
// clang-format on
};

View File

@ -25,6 +25,8 @@ set(OCCT_GeomToStep_FILES
GeomToStep_MakeBSplineSurfaceWithKnotsAndRationalBSplineSurface.hxx
GeomToStep_MakeCartesianPoint.cxx
GeomToStep_MakeCartesianPoint.hxx
GeomToStep_MakeCartesianTransformationOperator.cxx
GeomToStep_MakeCartesianTransformationOperator.hxx
GeomToStep_MakeCircle.cxx
GeomToStep_MakeCircle.hxx
GeomToStep_MakeCircle_gen.pxx

View File

@ -0,0 +1,49 @@
// Copyright (c) 2025 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 <GeomToStep_MakeCartesianTransformationOperator.hxx>
#include <GeomToStep_MakeCartesianPoint.hxx>
#include <GeomToStep_MakeDirection.hxx>
#include <StepGeom_CartesianTransformationOperator3d.hxx>
//=============================================================================
GeomToStep_MakeCartesianTransformationOperator::GeomToStep_MakeCartesianTransformationOperator(
const gp_Trsf& theTrsf,
const StepData_Factors& theLocalFactors)
{
gp_Trsf anInvTrsf = theTrsf;
anInvTrsf.Invert();
Standard_Real aScale = anInvTrsf.ScaleFactor();
gp_Mat anInvMat = anInvTrsf.HVectorialPart();
gp_Mat aMat = theTrsf.HVectorialPart();
gp_XYZ aTranslation = anInvTrsf.TranslationPart().Multiplied(aMat);
aTranslation.Reverse();
GeomToStep_MakeCartesianPoint aMkPoint(aTranslation, theLocalFactors.LengthFactor());
GeomToStep_MakeDirection aMkDir1(anInvMat.Row(1));
GeomToStep_MakeDirection aMkDir2(anInvMat.Row(2));
GeomToStep_MakeDirection aMkDir3(anInvMat.Row(3));
myTrsfOp = new StepGeom_CartesianTransformationOperator3d();
myTrsfOp->SetName(new TCollection_HAsciiString(""));
myTrsfOp->SetAxis1(aMkDir1.Value());
myTrsfOp->SetAxis2(aMkDir2.Value());
myTrsfOp->SetAxis3(aMkDir3.Value());
myTrsfOp->SetLocalOrigin(aMkPoint.Value());
myTrsfOp->SetScale(aScale);
done = Standard_True;
}

View File

@ -0,0 +1,53 @@
// Copyright (c) 2025 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 _GeomToStep_MakeCartesianTransformationOperator_HeaderFile
#define _GeomToStep_MakeCartesianTransformationOperator_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <GeomToStep_Root.hxx>
#include <StepData_StepModel.hxx>
#include <StepGeom_CartesianTransformationOperator3d.hxx>
class gp_Trsf;
//! This class creates a cartesian_transformation_operator from gp_Trsf.
//! This entity is used in OCCT to implement a transformation with scaling.
//! In case of other inputs without scaling use Axis2Placement3d.
class GeomToStep_MakeCartesianTransformationOperator : public GeomToStep_Root
{
public:
DEFINE_STANDARD_ALLOC
//! Main constructor.
//! @param[in] theTrsf Transformation to create the operator from it.
//! @param[in] theLocalFactors Unit scale factors
Standard_EXPORT GeomToStep_MakeCartesianTransformationOperator(
const gp_Trsf& theTrsf,
const StepData_Factors& theLocalFactors = StepData_Factors());
//! Returns the created entity.
//! @return The created value.
inline const Handle(StepGeom_CartesianTransformationOperator3d)& Value() const
{
return myTrsfOp;
}
private:
Handle(StepGeom_CartesianTransformationOperator3d) myTrsfOp;
};
#endif // _GeomToStep_MakeCartesianTransformationOperator_HeaderFile

View File

@ -22,6 +22,7 @@
#include <StepBasic_ProductDefinition.hxx>
#include <STEPConstruct_Assembly.hxx>
#include <StepGeom_Axis2Placement3d.hxx>
#include <StepGeom_CartesianTransformationOperator3d.hxx>
#include <StepRepr_ItemDefinedTransformation.hxx>
#include <StepRepr_NextAssemblyUsageOccurrence.hxx>
#include <StepRepr_ProductDefinitionShape.hxx>
@ -51,8 +52,25 @@ void STEPConstruct_Assembly::Init(const Handle(StepShape_ShapeDefinitionRepresen
thesr = Handle(StepShape_ShapeRepresentation)::DownCast(aSDR->UsedRepresentation());
thesr0 = Handle(StepShape_ShapeRepresentation)::DownCast(SDR0->UsedRepresentation());
theval.Nullify();
theax0 = Ax0;
theloc = AxLoc;
theax0 = Ax0;
theloc = AxLoc;
myIsCartesianTrsf = false;
}
//=================================================================================================
void STEPConstruct_Assembly::Init(
const Handle(StepShape_ShapeDefinitionRepresentation)& aSDR,
const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
const Handle(StepGeom_CartesianTransformationOperator3d)& theTrsfOp)
{
thesdr = aSDR;
thesdr0 = SDR0;
thesr = Handle(StepShape_ShapeRepresentation)::DownCast(aSDR->UsedRepresentation());
thesr0 = Handle(StepShape_ShapeRepresentation)::DownCast(SDR0->UsedRepresentation());
theval.Nullify();
myTrsfOp = theTrsfOp;
myIsCartesianTrsf = true;
}
//=================================================================================================
@ -91,10 +109,19 @@ void STEPConstruct_Assembly::MakeRelationship()
PDS->Init(pdsname, Standard_True, pdsdesc, CD);
// create transformation
Handle(StepRepr_ItemDefinedTransformation) ItemDef = new StepRepr_ItemDefinedTransformation;
Handle(TCollection_HAsciiString) idname = new TCollection_HAsciiString("");
Handle(TCollection_HAsciiString) idescr = new TCollection_HAsciiString("");
ItemDef->Init(idname, idescr, theax0, theloc);
Handle(Standard_Transient) aTrsfItem;
if (!myIsCartesianTrsf)
{
Handle(StepRepr_ItemDefinedTransformation) ItemDef = new StepRepr_ItemDefinedTransformation;
Handle(TCollection_HAsciiString) idname = new TCollection_HAsciiString("");
Handle(TCollection_HAsciiString) idescr = new TCollection_HAsciiString("");
ItemDef->Init(idname, idescr, theax0, theloc);
aTrsfItem = ItemDef;
}
else
{
aTrsfItem = myTrsfOp;
}
// create SRRWT
Handle(StepRepr_ShapeRepresentationRelationshipWithTransformation) SRRWT =
@ -102,7 +129,7 @@ void STEPConstruct_Assembly::MakeRelationship()
Handle(TCollection_HAsciiString) stname = new TCollection_HAsciiString("");
Handle(TCollection_HAsciiString) stescr = new TCollection_HAsciiString("");
StepRepr_Transformation StepTrans;
StepTrans.SetValue(ItemDef);
StepTrans.SetValue(aTrsfItem);
SRRWT->Init(stname, stescr, thesr, thesr0, StepTrans);
// create CDSR (final result, root)

View File

@ -24,6 +24,7 @@
class StepShape_ShapeDefinitionRepresentation;
class StepShape_ShapeRepresentation;
class StepGeom_Axis2Placement3d;
class StepGeom_CartesianTransformationOperator3d;
class StepRepr_NextAssemblyUsageOccurrence;
class StepShape_ContextDependentShapeRepresentation;
class Interface_Graph;
@ -52,6 +53,14 @@ public:
const Handle(StepGeom_Axis2Placement3d)& Ax0,
const Handle(StepGeom_Axis2Placement3d)& Loc);
//! Initialises with starting values
//! theTrsfOp : local transformation to apply, may have scaling factor
//! Makes a MappedItem
//! Resulting Value is returned by ItemValue
Standard_EXPORT void Init(const Handle(StepShape_ShapeDefinitionRepresentation)& theSR,
const Handle(StepShape_ShapeDefinitionRepresentation)& theSDR0,
const Handle(StepGeom_CartesianTransformationOperator3d)& theTrsfOp);
//! Make a (ShapeRepresentationRelationship,...WithTransformation)
//! Resulting Value is returned by ItemValue
Standard_EXPORT void MakeRelationship();
@ -74,13 +83,15 @@ public:
protected:
private:
Handle(StepShape_ShapeDefinitionRepresentation) thesdr;
Handle(StepShape_ShapeDefinitionRepresentation) thesdr0;
Handle(StepShape_ShapeRepresentation) thesr;
Handle(StepShape_ShapeRepresentation) thesr0;
Handle(Standard_Transient) theval;
Handle(StepGeom_Axis2Placement3d) theloc;
Handle(StepGeom_Axis2Placement3d) theax0;
Handle(StepShape_ShapeDefinitionRepresentation) thesdr;
Handle(StepShape_ShapeDefinitionRepresentation) thesdr0;
Handle(StepShape_ShapeRepresentation) thesr;
Handle(StepShape_ShapeRepresentation) thesr0;
Handle(Standard_Transient) theval;
Handle(StepGeom_Axis2Placement3d) theloc;
Handle(StepGeom_Axis2Placement3d) theax0;
Handle(StepGeom_CartesianTransformationOperator3d) myTrsfOp;
bool myIsCartesianTrsf;
};
#endif // _STEPConstruct_Assembly_HeaderFile

View File

@ -26,6 +26,7 @@
#include <Geom_Plane.hxx>
#include <Geom_Surface.hxx>
#include <GeomToStep_MakeAxis2Placement3d.hxx>
#include <GeomToStep_MakeCartesianTransformationOperator.hxx>
#include <Interface_Macros.hxx>
#include <Interface_MSG.hxx>
#include <Message_ProgressScope.hxx>
@ -41,6 +42,7 @@
#include <STEPControl_StepModelType.hxx>
#include <StepData_StepModel.hxx>
#include <StepGeom_Axis2Placement3d.hxx>
#include <StepGeom_CartesianTransformationOperator3d.hxx>
#include <StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx.hxx>
#include <StepGeom_Point.hxx>
#include <StepRepr_ShapeRepresentationRelationship.hxx>
@ -1656,8 +1658,8 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferCompound(
Message_ProgressScope aPS(theProgress, NULL, nbs);
for (i = 1; i <= nbs && aPS.More(); i++)
{
Handle(TransferBRep_ShapeMapper) subs = TransferBRep::ShapeMapper(FP, RepItemSeq->Value(i));
Handle(StepGeom_Axis2Placement3d) AX1;
Handle(TransferBRep_ShapeMapper) subs = TransferBRep::ShapeMapper(FP, RepItemSeq->Value(i));
Handle(StepGeom_GeometricRepresentationItem) AX1;
Handle(Transfer_Binder) bnd = TransferSubShape(subs,
SDR0,
@ -1709,7 +1711,7 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferCompound(
Handle(Transfer_Binder) STEPControl_ActorWrite::TransferSubShape(
const Handle(Transfer_Finder)& start,
const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
Handle(StepGeom_Axis2Placement3d)& AX1,
Handle(StepGeom_GeometricRepresentationItem)& AX1,
const Handle(Transfer_FinderProcess)& FP,
const StepData_Factors& theLocalFactors,
const Handle(TopTools_HSequenceOfShape)& shapeGroup,
@ -1781,14 +1783,39 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferSubShape(
// FP->GetTypedTransient (resbind,STANDARD_TYPE(StepShape_ShapeRepresentation),resultat);
// sdr->SetUsedRepresentation(resultat); // to be used by MakeItem
// make location for assembly placement
GeomToStep_MakeAxis2Placement3d mkax(aLoc, theLocalFactors);
const Handle(StepGeom_Axis2Placement3d)& AxLoc = mkax.Value();
AX1 = AxLoc;
// create assembly structures (CDSR, NAUO etc.)
STEPConstruct_Assembly mkitem;
mkitem.Init(sdr, SDR0, myContext.GetDefaultAxis(), AxLoc);
// make location for assembly placement
if (Abs(aLoc.ScaleFactor() - 1.0) > Precision::Confusion())
{
if (aStepModel->InternalParameters.WriteScalingTrsf)
FP->AddWarning(
start,
"The shape has a scaling factor, exported as cartesian_transformation_operator");
else
FP->AddWarning(start, "The shape has a scaling factor, skipped");
}
if (Abs(aLoc.ScaleFactor() - 1.0) < Precision::Confusion()
|| !aStepModel->InternalParameters.WriteScalingTrsf)
{
// create a new axis2placement3d
GeomToStep_MakeAxis2Placement3d mkax(aLoc, theLocalFactors);
mkitem.Init(sdr, SDR0, myContext.GetDefaultAxis(), mkax.Value());
AX1 = mkax.Value();
}
else
{
// create a new cartesian transformation
GeomToStep_MakeCartesianTransformationOperator aMaker(aLoc, theLocalFactors);
if (!aMaker.IsDone())
{
FP->AddFail(start, "The transfomation relation creation failed");
}
mkitem.Init(sdr, SDR0, aMaker.Value());
AX1 = aMaker.Value();
}
mkitem.MakeRelationship();
Handle(TColStd_HSequenceOfTransient) roots = myContext.GetRootsForAssemblyLink(mkitem);

View File

@ -29,7 +29,7 @@ class Transfer_Finder;
class Transfer_Binder;
class Transfer_FinderProcess;
class StepShape_ShapeDefinitionRepresentation;
class StepGeom_Axis2Placement3d;
class StepGeom_GeometricRepresentationItem;
class TopoDS_Shape;
class StepShape_NonManifoldSurfaceShapeRepresentation;
@ -55,7 +55,7 @@ public:
Standard_EXPORT Handle(Transfer_Binder) TransferSubShape(
const Handle(Transfer_Finder)& start,
const Handle(StepShape_ShapeDefinitionRepresentation)& SDR,
Handle(StepGeom_Axis2Placement3d)& AX1,
Handle(StepGeom_GeometricRepresentationItem)& AX1,
const Handle(Transfer_FinderProcess)& FP,
const StepData_Factors& theLocalFactors = StepData_Factors(),
const Handle(TopTools_HSequenceOfShape)& shapeGroup = NULL,

View File

@ -2131,6 +2131,10 @@ Standard_Boolean StepToGeom::MakeTransformation3d(
const gp_Ax3 result(Pgp, D3, D1);
CT.SetTransformation(result);
if (SCTO->HasScale())
{
CT.SetScaleFactor(SCTO->Scale());
}
CT = CT.Inverted(); //: n8 abv 16 Feb 99: tr8_as2_db.stp: reverse for accordance with LV tool
return Standard_True;
}

View File

@ -0,0 +1,51 @@
puts "================================================"
puts "OCP-1949: Apply a scaling transformation to STEP"
puts "================================================"
puts ""
pload OCAF
Close D1 -silent
Close D2 -silent
ReadGltf D1 [locate_data_file bug_ocp1948_PSU_Cartoning_subunit__right-01.01.01.03-CART-03_green_bottom.glb]
# apply parameters for tessellation export
set conf "
provider.STEP.OCC.write.schema : 5
provider.STEP.OCC.write.tessellated : 1
"
LoadConfiguration ${conf} -recursive on
param write.step.schema 5
param write.step.tessellated 1
WriteStep D1 "$imagedir/${casename}.stp"
ReadStep D2 "$imagedir/${casename}.stp"
XGetOneShape a1 D1
XGetOneShape a2 D2
# check center of gravity
set pos1 [vprops a1]
set pos2 [vprops a2]
set REF_X [lindex $pos1 9]
set REF_Y [lindex $pos1 12]
set REF_Z [lindex $pos1 15]
set tol 1e-4
if {([expr abs($REF_X - [lindex $pos2 9])] > $tol) ||
([expr abs($REF_Y - [lindex $pos2 12])] > $tol) ||
([expr abs($REF_Z - [lindex $pos2 15])] > $tol)} {
puts "Error: wrong position of the imported model."
}
# cleaning
Close D1
Close D2
file delete "$imagedir/${casename}.stp"
set conf "
provider.STEP.OCC.write.schema : 4
provider.STEP.OCC.write.tessellated : 2
"
LoadConfiguration ${conf} -recursive on

View File

@ -3,7 +3,6 @@ puts "0027142: Data Exchange - add possibility to set location in XCAFDoc_ShapeT
puts "=========="
puts ""
puts "TODO 0027142 ALL: Error: area of d1"
puts "TODO 0027142 ALL: Error: area of d2"
puts "TODO 0027142 ALL: Error: center of gravity"

View File

@ -199,6 +199,7 @@ provider.STEP.OCC.write.vismaterial : 0
provider.STEP.OCC.write.props : 1
provider.STEP.OCC.write.model.type : 0
provider.STEP.OCC.write.cleanduplicates : 0
provider.STEP.OCC.write.scaling.trsf : 1
provider.STEP.OCC.healing.tolerance3d : 1e-06
provider.STEP.OCC.healing.max.tolerance3d : 1
provider.STEP.OCC.healing.min.tolerance3d : 1e-07

View File

@ -143,6 +143,7 @@ provider.STEP.OCC.write.material : 1
provider.STEP.OCC.write.vismaterial : 0
provider.STEP.OCC.write.model.type : 0
provider.STEP.OCC.write.cleanduplicates : 0
provider.STEP.OCC.write.scaling.trsf : 1
provider.STEP.OCC.healing.tolerance3d : 1e-06
provider.STEP.OCC.healing.max.tolerance3d : 1
provider.STEP.OCC.healing.min.tolerance3d : 1e-07