Jump to content
DavidJr.

Parsing and rendering contents of a 3MF file

Recommended Posts

I have a VCL app and I am able to draw cross sections at any specific Z height using SDL Components (RChart) just fine, but I need to view solid objects.  Some of the methods here are resused from that app.

Share this post


Link to post

Hi David, 

 

I do not look reading/parsing part, but 3d can not work as is : It missed several things.

 

Not specially in order : 

- There are no viewport : If you do 3d app on "standart" FMX window (2d canvas), you must add a viewport (TViewport3D).

- You can not use TModel as is, it is a pure loading object : In fact, do not use TModel3d 🙂 use mesh collection instead.

- The dpr try to include a "*.windows.fmx" which break the project on opening step. Not a nice way for onboarding 🙂

 

- After corrections in 3d part, here what I can say : 
---> I believe there are some caveat in your "multi object reading". It is loading, but object are broken (missed processing init for sure) 
---> In single mesh, There are some issues in scaling (which is certainly in the file !)

---> Beside that, In Single mesh, it generally load a the object correctly !

 

- Above, some pictures, far to be perfect, but hope that help.

- Note that, surprisingly, MSPaint3D handle very well this kind of file. I use it for my test.

- You will find somes FMX3D examples under my github here, could perhaps help you on certain FMX3D behaviours.

 

- Note for next time :

--> Please indicate your dependancy the OXmlSAX unit came certainly from here ? - It should be cool to indicate that, in order to easely find dependancy.

--> Why not included a basic 3mf file to reproduce your problem ? for testing your "multiobject" ?

 

 

Vincent


image.thumb.png.6e9cbc294609c495186d1b63e5a62aa6.pngimage.thumb.png.cd9ae48afbb279867c38b1a72611da80.png

Unit1.fmx

Unit1.pas

Share this post


Link to post

Hi,

 

Sorry for the delay.  I decided to try and use the Lib3MF SDK for the consortium but the existing Pascal unit did not work even after adding in type QWork:  Uint64 (see attached (Unit_Lib3MF.pas).  So I started on my own one (renamed with _custom) (also attached)..  but I have a feeling that I should be really using the original Unit_Lib3MF.pas file but not sure what I am doing wrong.  this is where I got the unit: GitHub - 3MFConsortium/lib3mf: lib3mf is an implementation of the 3D Manufacturing Format file standard

 

This actually renders the 3D model but I am not able to get the metadata just as Object name from the file using their lib.

Unit_Lib3MF.pas

GLCADViewer.dpr

GLCADViewer.dproj

ProjectGroup1.groupproj

Unit_Lib3MF_custom.pas

Unit1.fmx

Unit1.pas

Unit1.Windows.fmx

Share this post


Link to post
Posted (edited)

Hi

As I see, you have now correct FMX 3d project, good point. 🙂

 

I understand your direction, but now it is not the same problem : You tryed to rebuild an "official" header unit and it is not a way that I would fellow personnaly. (in a update/support effort long-term perspective)

--> Have you try to use directly  the *original* unit with fpc instead of delphi (as it is apparently write for fpc, actually) to see if you succeded to read your file correctly (I would make a simple fpc console app, which read and convert the 3MF file as needed) ? And if it work, you have several solutions :

- Adapt this unit to work with delphi (beware of type - perhaps it is better to try conversion tools such as Yunkot one or Chet one .

- Alternatively, work on a personalized and simplified dll in C or FPC directy, which consume the *original* dll with correct and, above all, well supported header.

 

Edited by Vincent Gsell

Share this post


Link to post
7 hours ago, Vincent Gsell said:

Hi

As I see, you have now correct FMX 3d project, good point. 🙂

 

I understand your direction, but now it is not the same problem : You tryed to rebuild an "official" header unit and it is not a way that I would fellow personnaly. (in a update/support effort long-term perspective)

--> Have you try to use directly  the *original* unit with fpc instead of delphi (as it is apparently write for fpc, actually) to see if you succeded to read your file correctly (I would make a simple fpc console app, which read and convert the 3MF file as needed) ? And if it work, you have several solutions :

- Adapt this unit to work with delphi (beware of type - perhaps it is better to try conversion tools such as Yunkot one or Chet one .

- Alternatively, work on a personalized and simplified dll in C or FPC directy, which consume the *original* dll with correct and, above all, well supported header.

 

actually I am testing a unit I converted from FPC now.  (see attached)

Unit_Lib3MF.zip

Share this post


Link to post

Sounds nice !

 

I look further into the unit's Wrapper, and it is quite complicated ! Honestly, the TLib3MFPolymorphicFactory made my day. 🙂

 

--> Please, It will be cool if you can post your basic demo again using this "final" Wrapper ? Perhaps only the code to build an FMX3D object with this wrapper ? 


thx, 

Vincent

Share this post


Link to post

juste a side note

I tryed to just initialized the wrapper with last unit, and found somes glitches very quickly (AV on D12 on GetReleaseInformation) 

 

For exemples : 

 

	function TLib3MFWrapper.GetPrereleaseInformation(out APrereleaseInfo: String): Boolean;
	var
		ResultHasPrereleaseInfo: Byte;
		bytesNeededPrereleaseInfo: Cardinal;
		bytesWrittenPrereleaseInfo: Cardinal;
		bufferPrereleaseInfo: array of Char;
	begin
		ResultHasPrereleaseInfo := 0;
		bytesNeededPrereleaseInfo:= 0;
		bytesWrittenPrereleaseInfo:= 0;
		CheckError(nil, Lib3MFGetPrereleaseInformationFunc(ResultHasPrereleaseInfo, 0, bytesNeededPrereleaseInfo, nil));
		SetLength(bufferPrereleaseInfo, bytesNeededPrereleaseInfo);
		CheckError(nil, Lib3MFGetPrereleaseInformationFunc(ResultHasPrereleaseInfo, bytesNeededPrereleaseInfo, bytesWrittenPrereleaseInfo, @bufferPrereleaseInfo[0]));
		Result := (ResultHasPrereleaseInfo <> 0);
		APrereleaseInfo := String(@bufferPrereleaseInfo[0]);
	end;

 

Before the last line, i'll put a basic 

 

    begin

       [...]

        Result := (ResultHasPrereleaseInfo <> 0);

        If Result then

              APrereleaseInfo := String(@bufferPrereleaseInfo[0]);
    end;

 

This should avoid AV if you access the string passed by var in this call...

 

Share this post


Link to post
Posted (edited)
On 8/9/2024 at 6:16 AM, Vincent Gsell said:

juste a side note

I tryed to just initialized the wrapper with last unit, and found somes glitches very quickly (AV on D12 on GetReleaseInformation) 

 

For exemples : 

 


	function TLib3MFWrapper.GetPrereleaseInformation(out APrereleaseInfo: String): Boolean;
	var
		ResultHasPrereleaseInfo: Byte;
		bytesNeededPrereleaseInfo: Cardinal;
		bytesWrittenPrereleaseInfo: Cardinal;
		bufferPrereleaseInfo: array of Char;
	begin
		ResultHasPrereleaseInfo := 0;
		bytesNeededPrereleaseInfo:= 0;
		bytesWrittenPrereleaseInfo:= 0;
		CheckError(nil, Lib3MFGetPrereleaseInformationFunc(ResultHasPrereleaseInfo, 0, bytesNeededPrereleaseInfo, nil));
		SetLength(bufferPrereleaseInfo, bytesNeededPrereleaseInfo);
		CheckError(nil, Lib3MFGetPrereleaseInformationFunc(ResultHasPrereleaseInfo, bytesNeededPrereleaseInfo, bytesWrittenPrereleaseInfo, @bufferPrereleaseInfo[0]));
		Result := (ResultHasPrereleaseInfo <> 0);
		APrereleaseInfo := String(@bufferPrereleaseInfo[0]);
	end;

 

Before the last line, i'll put a basic 

 

    begin

       [...]

        Result := (ResultHasPrereleaseInfo <> 0);

        If Result then

              APrereleaseInfo := String(@bufferPrereleaseInfo[0]);
    end;

 

This should avoid AV if you access the string passed by var in this call...

 

I actually fixed a lot of that unit already...      thanks!

Edited by DavidJr.

Share this post


Link to post
Posted (edited)

by the way,  I am having a problem trying to add each mesh and having the meshes not sit on top of each other.  I attached the test project,  try loading a 3MF file with multiple objects you will see what I mean.  This is just a test app.  I was hoping to share this so other can use it,  but its worthless if I cannot specify a different color per object (mesh) in one TModel3D instance.

Unit_Lib3MF.pas

Test_lib3mf_app.zip

 

if I add all vertices and triangles into one mesh and add then the positions and scale of each object (all merged into one mesh are perfect, but then I cannot apply different colors.

Edited by DavidJr.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×