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.
// clang-format on
};
-#endif // _DESTEP_Parameters_HeaderFile
+#endif // _DEIGES_Parameters_HeaderFile
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);
}
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";
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
};
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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
#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>
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;
}
//=================================================================================================
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 =
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)
class StepShape_ShapeDefinitionRepresentation;
class StepShape_ShapeRepresentation;
class StepGeom_Axis2Placement3d;
+class StepGeom_CartesianTransformationOperator3d;
class StepRepr_NextAssemblyUsageOccurrence;
class StepShape_ContextDependentShapeRepresentation;
class Interface_Graph;
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();
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
#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>
#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>
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,
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,
// 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);
class Transfer_Binder;
class Transfer_FinderProcess;
class StepShape_ShapeDefinitionRepresentation;
-class StepGeom_Axis2Placement3d;
+class StepGeom_GeometricRepresentationItem;
class TopoDS_Shape;
class StepShape_NonManifoldSurfaceShapeRepresentation;
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,
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;
}
--- /dev/null
+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
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"
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
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