From b28f8b9517ff36942610a38d513d9e5fa6fde382 Mon Sep 17 00:00:00 2001
From: Alex Shvartzkop <dudesuchamazing@gmail.com>
Date: Sat, 11 May 2024 21:40:40 +0300
Subject: [PATCH] Data Exchange, VRML - Handle whichChoice / choice in VRML 2.0
 Switch node.

---
 src/VrmlData/VrmlData_Group.cxx | 13 +++++++++++--
 src/VrmlData/VrmlData_Group.hxx |  4 +++-
 src/VrmlData/VrmlData_Scene.cxx | 15 ++++++++++++---
 src/VrmlData/VrmlData_Scene.hxx |  1 +
 4 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/src/VrmlData/VrmlData_Group.cxx b/src/VrmlData/VrmlData_Group.cxx
index 27b10e54c2..b431d7f788 100644
--- a/src/VrmlData/VrmlData_Group.cxx
+++ b/src/VrmlData/VrmlData_Group.cxx
@@ -45,6 +45,7 @@ VrmlData_Group::VrmlData_Group (const VrmlData_Scene&   theScene,
                                 const Standard_Boolean  isTransform)
   : VrmlData_Node     (theScene, theName),
     myIsTransform     (isTransform),
+    myWhichChoice     (-3),
     myNodes           (theScene.Allocator())
 {}
 
@@ -179,7 +180,15 @@ VrmlData_ErrorStatus VrmlData_Group::Read (VrmlData_InBuffer& theBuffer)
       aStatus = Scene().ReadXYZ (theBuffer, aBoxSize,
                                  Standard_True, Standard_False);
 
-    else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "children")) {
+    else if (VRMLDATA_LCOMPARE(theBuffer.LinePtr, "whichChoice")) {
+        long aWhichChoice(-3);
+        aStatus = VrmlData_Node::ReadInteger(theBuffer, aWhichChoice);
+        myWhichChoice = aWhichChoice;
+    }
+
+    else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "children") ||
+             VRMLDATA_LCOMPARE (theBuffer.LinePtr, "choice"))
+    {
       Standard_Boolean isBracketed (Standard_False);
       // Read the opening bracket for the list of children
       if (!OK(aStatus, VrmlData_Scene::ReadLine(theBuffer)))
@@ -514,7 +523,7 @@ VrmlData_ErrorStatus VrmlData_Group::Read (VrmlData_InBuffer& theBuffer)
 void VrmlData_Group::Shape (TopoDS_Shape&                       theShape,
                             VrmlData_DataMapOfShapeAppearance * pMapApp)
 {
-  VrmlData_Scene::createShape (theShape, myNodes, pMapApp);
+  VrmlData_Scene::createShape (theShape, myNodes, myWhichChoice, pMapApp);
   theShape.Location(myTrsf, Standard_False);
 }
 
diff --git a/src/VrmlData/VrmlData_Group.hxx b/src/VrmlData/VrmlData_Group.hxx
index 1068ec758f..06a62cc363 100644
--- a/src/VrmlData/VrmlData_Group.hxx
+++ b/src/VrmlData/VrmlData_Group.hxx
@@ -42,7 +42,8 @@ class VrmlData_Group : public VrmlData_Node
    *   Allocator used for the list of children
    */
   VrmlData_Group (const Standard_Boolean  isTransform = Standard_False) 
-    : myIsTransform     (isTransform)
+    : myIsTransform     (isTransform),
+      myWhichChoice     (-3)
   {}
 
   /**
@@ -164,6 +165,7 @@ class VrmlData_Group : public VrmlData_Node
   // ---------- PRIVATE FIELDS ----------
 
   Standard_Boolean      myIsTransform;
+  Standard_Integer      myWhichChoice;
   VrmlData_ListOfNode   myNodes;
   Bnd_B3f               myBox;
   gp_Trsf               myTrsf;
diff --git a/src/VrmlData/VrmlData_Scene.cxx b/src/VrmlData/VrmlData_Scene.cxx
index 01adb4d2b0..d5ed5a3d71 100644
--- a/src/VrmlData/VrmlData_Scene.cxx
+++ b/src/VrmlData/VrmlData_Scene.cxx
@@ -631,7 +631,7 @@ VrmlData_ErrorStatus VrmlData_Scene::createNode
 VrmlData_Scene::operator TopoDS_Shape () const
 {
   TopoDS_Shape aShape;
-  VrmlData_Scene::createShape (aShape, myLstNodes, 0L);
+  VrmlData_Scene::createShape (aShape, myLstNodes, -3, 0L);
   return aShape;
 }
 
@@ -643,7 +643,7 @@ VrmlData_Scene::operator TopoDS_Shape () const
 TopoDS_Shape VrmlData_Scene::GetShape (VrmlData_DataMapOfShapeAppearance& aMap)
 {
   TopoDS_Shape aShape;
-  VrmlData_Scene::createShape (aShape, myLstNodes, &aMap);
+  VrmlData_Scene::createShape (aShape, myLstNodes, -3, &aMap);
   return aShape;
 }
 
@@ -655,6 +655,7 @@ TopoDS_Shape VrmlData_Scene::GetShape (VrmlData_DataMapOfShapeAppearance& aMap)
 void VrmlData_Scene::createShape
                 (TopoDS_Shape&                      outShape,
                  const VrmlData_ListOfNode&         lstNodes,
+                 const Standard_Integer             theWhichChoice,
                  VrmlData_DataMapOfShapeAppearance* pMapShapeApp)
 {
   TopoDS_Shape aSingleShape;  // used when there is a single ShapeNode
@@ -665,7 +666,15 @@ void VrmlData_Scene::createShape
   aSingleShape.Orientation(TopAbs_FORWARD);
 
   Iterator anIter (lstNodes);
-  for (; anIter.More(); anIter.Next()) {
+  for (Standard_Integer idx = 0; anIter.More(); anIter.Next(), idx++) {
+    // Handle Switch choice
+    if (theWhichChoice >= 0) {
+      if (idx != theWhichChoice)
+        continue;
+    }
+    else if (theWhichChoice != -3)
+      continue;
+
     // Try a Shape type of node
     const Handle(VrmlData_ShapeNode) aNodeShape =
       Handle(VrmlData_ShapeNode)::DownCast (anIter.Value());
diff --git a/src/VrmlData/VrmlData_Scene.hxx b/src/VrmlData/VrmlData_Scene.hxx
index 495d8dea8e..1cc8477440 100644
--- a/src/VrmlData/VrmlData_Scene.hxx
+++ b/src/VrmlData/VrmlData_Scene.hxx
@@ -366,6 +366,7 @@ class VrmlData_Scene
    */
   Standard_EXPORT static void   createShape (TopoDS_Shape&          outShape,
                                              const VrmlData_ListOfNode&,
+                                             const Standard_Integer theWhichChoice,
                                              VrmlData_DataMapOfShapeAppearance*);
 
 
-- 
2.39.1.windows.1

