problem importing 3ds files

Discuss and ask questions about CAD VCL (Delphi and C++ Builder).

Moderators: SDS, support, admin

Post Reply
cmOdeon
Posts: 11
Joined: 08 Apr 2019, 11:23

problem importing 3ds files

Post by cmOdeon » 19 Mar 2021, 15:50

Hi,

we are having a problem with a user importing 3ds files in our software (developed with Delphi). The software mimics the import procedure in the 3D demo which also fails to import this kind of 3ds files. I can see the import produces an exception when the 3ds file is read in Tsg3DNavigator.LoadFromFile
Image1.png
Image1.png (15.56 KiB) Viewed 4071 times
I was trying to narrow the problem and found a couple of things:

1) TMaterial3DS.shininess which is defined as a single in Type3DS. Then in GetOrAllocateMaterial, internal function of TGL3DSVectorFile.LoadFromStream in GLFile3DS.pas, shininess of a given material is stored in the property Shininess of the class TGLShader which has the type TShininess = 0..128. This is done in line 1749 of GLFile3DS.pas

Code: Select all

 Shininess := MaxInteger(0, integer(round((material.Shininess) * 128)));  
given above line I assume material.Shininess is a Single meant for the range [0,1]. However, I can see that for the 3ds files of my user material.Shininess of one of the materials is 255 (like if it where meant in the range [0,255] rather than [0,1]). then the result of the left hand side in the above line of code is out of the range [0,128] which causes a range check error that triggers an exception. In our software we don't use shininess for anything so I just replaced the line by

Code: Select all

 Shininess := MinInteger(MaxInteger(0, integer(round((material.Shininess) * 128))), 128);   
2) Later in the execution flow, I had a second problem regarding camera objects in TGL3DSVectorFile.LoadFromStream at GLFile3DS.pas around line 2456

Code: Select all

  camera_mesh.LoadAnimation(KeyFramer.CameraMotion[I]);  
I can see in the 3ds files provided by the user, the argument of loadAnimation function is nil which causes an exception inside the function. Our software neither uses this camera for anything so I just skip the loading when the argument is nil like this

Code: Select all

 if Assigned(KeyFramer.CameraMotion[I]) then
  camera_mesh.LoadAnimation(KeyFramer.CameraMotion[I]);   

this is probably not a good solution because then I have an exception when freeing the navigator. Tsg3DNavigator.Free

When we built the importer in our software we tested a number of 3ds files having no problems with the import, however the user claims that all the 3ds files they create fail to be open, we suspect the problem might be related with the way the files are constructed. The 3ds files that cause the problem are created in Rhino (Version 6 SR11) following these instructions:

Select complete model, type command _mesh
Recommendation for the exact settings of the polygon mesh:
Density: 0.5
Maximum angle: 1.0
Maximum aspect ratio: 0.0
Minimum edge length: 1.0
Maximum edge length: 0.0 
Maximum edge to face distance: 0.01
Minimum squares of initial mesh: 0
Refine polygon mesh: Check
Serrated seams: Check
Simple planes: Check
Compress textures: Uncheck
Obviously, each model has its own history, and the same settings cannot always be used.
Delete "old" surfaces so that only polygon meshes remain.
Save model as 3ds

an example 3ds file producing the exception is also attached as a zip file.

It would be really helpful if you could take a look to these problems and share a solution with us. Also Do you think a change on the workflow for the creation of the model might help to avoid the problems? Thank you

Regards, Carlos
Attachments
20210209_Grossraumbuero.zip
(39.68 KiB) Downloaded 455 times

support
Posts: 3271
Joined: 30 Mar 2005, 11:36
Contact:

Re: problem importing 3ds files

Post by support » 07 Apr 2021, 00:05

Hello Carlos,

Sorry for the delay in our reply.

1) For your information, shininess in OpenGL is a number in the range from 0 to 128. Apparently, the problem is that Rhinoceros 6 uses a different range for the Shininess property of material. Could you please check if the range check error occurs only with Rhino files?

2) KeyFramer.CameraMotionCount = 0 for your .3ds file, so the call

Code: Select all

camera_mesh.LoadAnimation(KeyFramer.CameraMotion[I]);
should be skipped in this case. To free the navigator, you may call Tsg3DDrawingNavigator.Free.

Mikhail
Technical Support E-mail: support@cadsofttools.com
Chat support on Skype: cadsofttools.support

cmOdeon
Posts: 11
Joined: 08 Apr 2019, 11:23

Re: problem importing 3ds files

Post by cmOdeon » 07 Apr 2021, 13:05

Hi Mikhail,

Thank you for your replay!

I cannot confirm that is only Rhino that produces the shininess exception, but according to the user all the 3ds models created with Rhino have the issue. Usually I get my .3ds models from the internet and the software used for their generation is unknown, neither we have a software to generate .3ds models.

About the choice of navigator to loadFromFile, I am using Tsg3DNavigator rather than Tsg3DDrawingNavigator because couldn't find other way to access the list of objects in the model (i.e. MeshObjects). the code is very small:

Code: Select all

var N3D                 : Tsg3DNavigator;
    CurrMeshObject      : TMeshObject;
    ExcludeFrozenLayers : Boolean; // user defined, we can say it is true in this example
.......
.......

if (cadFileType = cad3DS) then // use Tsg3DNavigator to extract Material from .3ds file
begin
  try
    N3D := Tsg3DNavigator.Create(nil);

    N3D.GLFreeForm.AutoCentering := [macCenterX, macCenterY, macCenterZ];

    N3D.LoadFromFile(DxfFileName);

    // exclude Frozen Layers
    for i := 0 to N3D.GLFreeForm.MeshObjects.Count-1 do
    begin
      CurrMeshObject := N3D.GLFreeForm.MeshObjects.Items[i];
      // Skip objects in invisible layers
      if ExcludeFrozenLayers AND (NOT CurrMeshObject.visible) then continue;
      Create3DFacesFromFromMeshObjectTriangles(CurrMeshObject);
    end;

  finally
    try    {$R-} N3D.Free; {$R+}
    except {$IFDEF Debug} showmessage('breaks when freeing Tsg3DNavigator'); {$ENDIF}
    end;
  end;
end;
Create3DFacesFromFromMeshObjectTriangles is a function of my own that loops on CurrMeshObject.FaceGroups and collects all triangles in the mesh along with materialNames. This information is passed on to the internal variables of our software which has its own navigators.

Is there a way to do this with a Tsg3DDrawingNavigator?

best regards, Carlos

support
Posts: 3271
Joined: 30 Mar 2005, 11:36
Contact:

Re: problem importing 3ds files

Post by support » 07 Apr 2021, 22:30

Hello Carlos,

Tsg3DDrawingNavigator component provides access to the Tsg3DNavigator object through a Tsg3DDrawingNavigator.Navigator3D property.

Mikhail
Technical Support E-mail: support@cadsofttools.com
Chat support on Skype: cadsofttools.support

cmOdeon
Posts: 11
Joined: 08 Apr 2019, 11:23

Re: problem importing 3ds files

Post by cmOdeon » 13 Apr 2021, 10:15

Mikhail,

I think my problem is solved. thank you for the help!

regards, Carlos

Post Reply