From: ika Date: Mon, 30 Sep 2024 11:12:05 +0000 (+0100) Subject: Data Exchange, Gltf Export - Metadata support #79 X-Git-Tag: V7_9_0_beta1~147 X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=5cc7cbea8b673b35054d3d35612d4c3b0a5458bb;p=occt.git Data Exchange, Gltf Export - Metadata support #79 Add supporting of metadata key-value export into extras section of each node. --- diff --git a/src/RWGltf/RWGltf_CafWriter.cxx b/src/RWGltf/RWGltf_CafWriter.cxx index aa86708d39..e7ef51e957 100644 --- a/src/RWGltf/RWGltf_CafWriter.cxx +++ b/src/RWGltf/RWGltf_CafWriter.cxx @@ -1978,6 +1978,8 @@ void RWGltf_CafWriter::writeNodes (const Handle(TDocStd_Document)& theDocument, #ifdef HAVE_RAPIDJSON Standard_ProgramError_Raise_if (myWriter.get() == NULL, "Internal error: RWGltf_CafWriter::writeNodes()"); + Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(theDocument->Main()); + // Prepare full indexed map of scene nodes in correct order. RWGltf_GltfSceneNodeMap aSceneNodeMapWithChildren; // indexes starting from 1 for (XCAFPrs_DocumentExplorer aDocExplorer (theDocument, theRootLabels, XCAFPrs_DocumentExplorerFlags_None); @@ -2130,6 +2132,18 @@ void RWGltf_CafWriter::writeNodes (const Handle(TDocStd_Document)& theDocument, myWriter->String (aNodeName.ToCString()); } } + { + Handle(TDataStd_NamedData) aNamedData = aShapeTool->GetNamedProperties(aDocNode.Label); + Handle(TDataStd_NamedData) aRefNamedData = aShapeTool->GetNamedProperties(aDocNode.RefLabel); + if (!aNamedData.IsNull() || !aRefNamedData.IsNull()) + { + myWriter->Key("extras"); + myWriter->StartObject(); + writeExtrasAttributes(aNamedData); + writeExtrasAttributes(aRefNamedData); + myWriter->EndObject(); + } + } myWriter->EndObject(); } myWriter->EndArray(); @@ -2142,6 +2156,104 @@ void RWGltf_CafWriter::writeNodes (const Handle(TDocStd_Document)& theDocument, #endif } +// ======================================================================= +// function : writeExtrasAttributes +// purpose : +// ======================================================================= +void RWGltf_CafWriter::writeExtrasAttributes(const Handle(TDataStd_NamedData)& theNamedData) +{ +#ifdef HAVE_RAPIDJSON + Standard_ProgramError_Raise_if(myWriter.get() == NULL, "Internal error: RWGltf_CafWriter::writeExtrasAttributes()"); + + if (theNamedData.IsNull()) + return; + theNamedData->LoadDeferredData(); + if (theNamedData->HasIntegers()) + { + const TColStd_DataMapOfStringInteger& anIntProperties = theNamedData->GetIntegersContainer(); + for (TColStd_DataMapIteratorOfDataMapOfStringInteger anIter(anIntProperties); + anIter.More(); anIter.Next()) + { + TCollection_AsciiString aKey(anIter.Key()); + myWriter->Key(aKey.ToCString()); + myWriter->Int(anIter.Value()); + } + } + if (theNamedData->HasReals()) + { + const TDataStd_DataMapOfStringReal& aRealProperties = theNamedData->GetRealsContainer(); + for (TDataStd_DataMapIteratorOfDataMapOfStringReal anIter(aRealProperties); + anIter.More(); anIter.Next()) + { + TCollection_AsciiString aKey(anIter.Key()); + myWriter->Key(aKey.ToCString()); + myWriter->Double(anIter.Value()); + } + } + if (theNamedData->HasStrings()) + { + const TDataStd_DataMapOfStringString& aStringProperties = theNamedData->GetStringsContainer(); + for (TDataStd_DataMapIteratorOfDataMapOfStringString anIter(aStringProperties); + anIter.More(); anIter.Next()) + { + TCollection_AsciiString aKey(anIter.Key()); + TCollection_AsciiString aValue(anIter.Value()); + myWriter->Key(aKey.ToCString()); + myWriter->String(aValue.ToCString()); + } + } + if (theNamedData->HasBytes()) + { + const TDataStd_DataMapOfStringByte& aByteProperties = theNamedData->GetBytesContainer(); + for (TDataStd_DataMapOfStringByte::Iterator anIter(aByteProperties); + anIter.More(); anIter.Next()) + { + TCollection_AsciiString aKey(anIter.Key()); + myWriter->Key(aKey.ToCString()); + myWriter->Int(anIter.Value()); + } + } + if (theNamedData->HasArraysOfIntegers()) + { + const TDataStd_DataMapOfStringHArray1OfInteger& anArrayIntegerProperties = + theNamedData->GetArraysOfIntegersContainer(); + for (TDataStd_DataMapOfStringHArray1OfInteger::Iterator anIter(anArrayIntegerProperties); + anIter.More(); anIter.Next()) + { + TCollection_AsciiString aKey(anIter.Key()); + myWriter->Key(aKey.ToCString()); + myWriter->StartArray(); + for (TColStd_HArray1OfInteger::Iterator anSubIter(anIter.Value()->Array1()); + anSubIter.More(); anSubIter.Next()) + { + myWriter->Int(anSubIter.Value()); + } + myWriter->EndArray(); + } + } + if (theNamedData->HasArraysOfReals()) + { + const TDataStd_DataMapOfStringHArray1OfReal& anArrayRealsProperties = + theNamedData->GetArraysOfRealsContainer(); + for (TDataStd_DataMapOfStringHArray1OfReal::Iterator anIter(anArrayRealsProperties); + anIter.More(); anIter.Next()) + { + TCollection_AsciiString aKey(anIter.Key()); + myWriter->Key(aKey.ToCString()); + myWriter->StartArray(); + for (TColStd_HArray1OfReal::Iterator anSubIter(anIter.Value()->Array1()); + anSubIter.More(); anSubIter.Next()) + { + myWriter->Double(anSubIter.Value()); + } + myWriter->EndArray(); + } + } +#else + (void)theNamedData; +#endif +} + // ======================================================================= // function : writeSamplers // purpose : diff --git a/src/RWGltf/RWGltf_CafWriter.hxx b/src/RWGltf/RWGltf_CafWriter.hxx index b2cfa9ba91..fe642bd5e6 100644 --- a/src/RWGltf/RWGltf_CafWriter.hxx +++ b/src/RWGltf/RWGltf_CafWriter.hxx @@ -34,6 +34,7 @@ class RWMesh_FaceIterator; class RWGltf_GltfOStreamWriter; class RWGltf_GltfMaterialMap; class RWGltf_GltfSceneNodeMap; +class TDataStd_NamedData; class TDocStd_Document; //! glTF writer context from XCAF document. @@ -349,6 +350,10 @@ protected: //! @param theMaterialMap [out] map of materials, filled with textures Standard_EXPORT virtual void writeTextures (const RWGltf_GltfSceneNodeMap& theSceneNodeMap); + //! Write nodes.extras section with key-value attributes. + //! @param theNamedData [in] attributes map to process. + Standard_EXPORT virtual void writeExtrasAttributes(const Handle(TDataStd_NamedData)& theNamedData); + protected: //! Shape + Style pair. diff --git a/tests/metadata/end b/tests/metadata/end deleted file mode 100644 index fc54e89d6c..0000000000 --- a/tests/metadata/end +++ /dev/null @@ -1,98 +0,0 @@ -# Set flag dump_file to 1 in order to regenerate script files with actual data -# used as reference. In this mode all tests intentionally report failure. -set dump_file 0 -######################################################################## -set mist 0; -set todo_msg "" -set todo_mask "puts \"TODO CR00000 ALL: " -set end_line "\" \n" -################################################################## - -# Read original file -if { [string length $filename] > 1} { - set path_file [locate_data_file $filename] - if { [catch { ReadFile D $path_file } catch_result] } { - set err_msg "Error: file was not read - exception " - puts $err_msg - append todo_msg $todo_mask $err_msg $end_line - set mist 1 - } -} else { - set mist 1 -} - -# Get information about translation -if { $mist < 1} { - puts "" - set prop [ XGetProperties D ] - - if { [llength $prop] < 0 } { - puts " Metadata was NOT provided" - } -} -if { $mist < 1} { - # Close the document - if { [catch { Close D } catch_result] } { - set err_msg "Error : cannot close a document D - exception" - puts $err_msg - append todo_msg $todo_mask $err_msg $end_line - } -} - -if { $mist != 1 } { - puts "" - set result "" - append result [format $prop] -} - -set ref_Compare 0 -# Put reference data to the test script file if option "dump" is set -if { $dump_file == 1 } { - set fd_stream [open $dirname/$groupname/$gridname/$casename w] - fconfigure $fd_stream -encoding utf-8 - puts $fd_stream "# !!!! This file is generated automatically, do not edit manually! See end script" - puts $fd_stream "set filename $filename" - if { $mist != 1 } { - puts $fd_stream "" - puts $fd_stream "set ref_data \{" - puts $fd_stream $result - puts $fd_stream "\}" - } - close $fd_stream -} elseif { $mist != 1 } { - puts "========================== Comparison with reference data ========" - - # Comparison of reference data with obtained result - set ref_list [split $ref_data \n] - set cur_list [split $result \n] - set nb_ref [llength $ref_list] - for { set i 0 } { $i < $nb_ref } { incr i } { - set j [expr $i + 1] - set refstr [lindex $ref_list $j] - set curstr [lindex $cur_list $i] - set isOK 1; - - if {[string equal $refstr $curstr] == 0} { - incr ref_Compare - puts "Reference data - $refstr\n" - puts "Current data - $curstr\n" - puts "----------------------------------------------\n" - } - } -} - -if { $dump_file != 0 } { - puts "Error : Running in regeneration mode, comparison was not performed!" - if { $mist != 1 } { - puts "Generation of test file $groupname/$gridname/$casename successful" - } else { - puts "Generation of reference data failed" - } -} else { - if { $ref_Compare >= 1} { - puts "Error : differences with reference data found : $ref_Compare" - } else { - puts "Comparison of current result with reference data - OK\n" - } -} -puts "TEST COMPLETED" diff --git a/tests/metadata/gltf_export/A1 b/tests/metadata/gltf_export/A1 new file mode 100644 index 0000000000..836d0e916f --- /dev/null +++ b/tests/metadata/gltf_export/A1 @@ -0,0 +1,3 @@ +# !!!! This file is generated automatically, do not edit manually! See end script +set filename bug28345_30338.stp +set ref_size 5896 diff --git a/tests/metadata/gltf_export/A2 b/tests/metadata/gltf_export/A2 new file mode 100644 index 0000000000..734de94be3 --- /dev/null +++ b/tests/metadata/gltf_export/A2 @@ -0,0 +1,3 @@ +# !!!! This file is generated automatically, do not edit manually! See end script +set filename bug28389_CONFIDENTIAL_SHEET_METAL_F3D.stp +set ref_size 86278 diff --git a/tests/metadata/gltf_export/A3 b/tests/metadata/gltf_export/A3 new file mode 100644 index 0000000000..b1020fdb4c --- /dev/null +++ b/tests/metadata/gltf_export/A3 @@ -0,0 +1,3 @@ +# !!!! This file is generated automatically, do not edit manually! See end script +set filename bug28444_nist_ftc_06_asme1_ct5240_rd.stp +set ref_size 85383 diff --git a/tests/metadata/gltf_export/A4 b/tests/metadata/gltf_export/A4 new file mode 100644 index 0000000000..6cdc3c7549 --- /dev/null +++ b/tests/metadata/gltf_export/A4 @@ -0,0 +1,3 @@ +# !!!! This file is generated automatically, do not edit manually! See end script +set filename bug29525_rev_part_neu_01.prt_converted_from_datakit.stp +set ref_size 80996 diff --git a/tests/metadata/gltf_export/A5 b/tests/metadata/gltf_export/A5 new file mode 100644 index 0000000000..3e132d8a79 --- /dev/null +++ b/tests/metadata/gltf_export/A5 @@ -0,0 +1,3 @@ +# !!!! This file is generated automatically, do not edit manually! See end script +set filename bug29633_nist_ctc_05_asme1_ap242-1.stp +set ref_size 69902 diff --git a/tests/metadata/gltf_export/A6 b/tests/metadata/gltf_export/A6 new file mode 100644 index 0000000000..db247e76eb --- /dev/null +++ b/tests/metadata/gltf_export/A6 @@ -0,0 +1,3 @@ +# !!!! This file is generated automatically, do not edit manually! See end script +set filename bug29803.stp +set ref_size 17032 diff --git a/tests/metadata/gltf_export/A7 b/tests/metadata/gltf_export/A7 new file mode 100644 index 0000000000..3bb42faecf --- /dev/null +++ b/tests/metadata/gltf_export/A7 @@ -0,0 +1,3 @@ +# !!!! This file is generated automatically, do not edit manually! See end script +set filename sp7_04-do-242.stp +set ref_size 224779 diff --git a/tests/metadata/gltf_export/A8 b/tests/metadata/gltf_export/A8 new file mode 100644 index 0000000000..8c2edc7f18 --- /dev/null +++ b/tests/metadata/gltf_export/A8 @@ -0,0 +1,3 @@ +# !!!! This file is generated automatically, do not edit manually! See end script +set filename bug32087_part.stp +set ref_size 15789 diff --git a/tests/metadata/gltf_export/A9 b/tests/metadata/gltf_export/A9 new file mode 100644 index 0000000000..2428cb4e23 --- /dev/null +++ b/tests/metadata/gltf_export/A9 @@ -0,0 +1,3 @@ +# !!!! This file is generated automatically, do not edit manually! See end script +set filename nist_ftc_08_asme1_ap242-2.stp +set ref_size 118200 diff --git a/tests/metadata/gltf_export/begin b/tests/metadata/gltf_export/begin new file mode 100644 index 0000000000..56cb94b803 --- /dev/null +++ b/tests/metadata/gltf_export/begin @@ -0,0 +1 @@ +pload MODELING diff --git a/tests/metadata/gltf_export/end b/tests/metadata/gltf_export/end new file mode 100644 index 0000000000..8e4881b137 --- /dev/null +++ b/tests/metadata/gltf_export/end @@ -0,0 +1,39 @@ +# Set flag dump_file to 1 in order to regenerate script files with actual data +# used as reference. In this mode all tests intentionally report failure. +set dump_file 0 + +# Read original file +if { [string length $filename] > 1} { + set path_file [locate_data_file $filename] + if { [catch { ReadFile D $path_file } catch_result] } { + set err_msg "Error: file was not read - exception " + puts $err_msg + } +} + +# mesh the shape before Gltf writing +XGetOneShape a D +incmesh a 0.1 + +# write file +WriteGltf D $imagedir/${casename}_D_First.gltf +set aSize [file size $imagedir/${casename}_D_First.gltf] + +if { $dump_file == 1 } { + set fd_stream [open $dirname/$groupname/$gridname/$casename w] + puts $fd_stream "# !!!! This file is generated automatically, do not edit manually! See end script" + puts $fd_stream "set filename $filename" + puts $fd_stream "set ref_size $aSize" + close $fd_stream + puts "Error : Running in regeneration mode, comparison was not performed!" +} else { + if {$aSize != $ref_size} { + puts "Error: Wrong file size $aSize instead of $ref_size" + } +} + +# finalize scenario +Close D +file delete $imagedir/${casename}_D_First.gltf +file delete $imagedir/${casename}_D_First.bin +puts "TEST COMPLETED" diff --git a/tests/metadata/grids.list b/tests/metadata/grids.list index c7e242aaea..3dc7702c6b 100644 --- a/tests/metadata/grids.list +++ b/tests/metadata/grids.list @@ -1 +1,2 @@ 001 step +002 gltf_export diff --git a/tests/metadata/step/end b/tests/metadata/step/end new file mode 100644 index 0000000000..fc54e89d6c --- /dev/null +++ b/tests/metadata/step/end @@ -0,0 +1,98 @@ +# Set flag dump_file to 1 in order to regenerate script files with actual data +# used as reference. In this mode all tests intentionally report failure. +set dump_file 0 +######################################################################## +set mist 0; +set todo_msg "" +set todo_mask "puts \"TODO CR00000 ALL: " +set end_line "\" \n" +################################################################## + +# Read original file +if { [string length $filename] > 1} { + set path_file [locate_data_file $filename] + if { [catch { ReadFile D $path_file } catch_result] } { + set err_msg "Error: file was not read - exception " + puts $err_msg + append todo_msg $todo_mask $err_msg $end_line + set mist 1 + } +} else { + set mist 1 +} + +# Get information about translation +if { $mist < 1} { + puts "" + set prop [ XGetProperties D ] + + if { [llength $prop] < 0 } { + puts " Metadata was NOT provided" + } +} +if { $mist < 1} { + # Close the document + if { [catch { Close D } catch_result] } { + set err_msg "Error : cannot close a document D - exception" + puts $err_msg + append todo_msg $todo_mask $err_msg $end_line + } +} + +if { $mist != 1 } { + puts "" + set result "" + append result [format $prop] +} + +set ref_Compare 0 +# Put reference data to the test script file if option "dump" is set +if { $dump_file == 1 } { + set fd_stream [open $dirname/$groupname/$gridname/$casename w] + fconfigure $fd_stream -encoding utf-8 + puts $fd_stream "# !!!! This file is generated automatically, do not edit manually! See end script" + puts $fd_stream "set filename $filename" + if { $mist != 1 } { + puts $fd_stream "" + puts $fd_stream "set ref_data \{" + puts $fd_stream $result + puts $fd_stream "\}" + } + close $fd_stream +} elseif { $mist != 1 } { + puts "========================== Comparison with reference data ========" + + # Comparison of reference data with obtained result + set ref_list [split $ref_data \n] + set cur_list [split $result \n] + set nb_ref [llength $ref_list] + for { set i 0 } { $i < $nb_ref } { incr i } { + set j [expr $i + 1] + set refstr [lindex $ref_list $j] + set curstr [lindex $cur_list $i] + set isOK 1; + + if {[string equal $refstr $curstr] == 0} { + incr ref_Compare + puts "Reference data - $refstr\n" + puts "Current data - $curstr\n" + puts "----------------------------------------------\n" + } + } +} + +if { $dump_file != 0 } { + puts "Error : Running in regeneration mode, comparison was not performed!" + if { $mist != 1 } { + puts "Generation of test file $groupname/$gridname/$casename successful" + } else { + puts "Generation of reference data failed" + } +} else { + if { $ref_Compare >= 1} { + puts "Error : differences with reference data found : $ref_Compare" + } else { + puts "Comparison of current result with reference data - OK\n" + } +} +puts "TEST COMPLETED"