Export of .mpd to single 'stand-alone' .ldr file ?


Export of .mpd to single 'stand-alone' .ldr file ?
#1
Hi,

Can anyone point me in the direction of an application or utility which will take a multi-part ldraw file (i.e. an .mpd file) and convert it into a single 'standalone' LDR file ?

i.e. something which takes an mpd file and outputs the 'absolute' position and rotation of each part in the model referenced to the origin - not to another part of the model.

Hope that makes sense...

I've had a go writing a conversion myself but got bogged down - has to be recursive I think for multiple 'nested' models.

If no such thing exists could any one give me some tips (not code necessarily) but the method I would need follow to acheive what I'm after ?

Thanks.

Rob @ TCBUK
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#2
Interesting idea, I don't know of a tool that can do this in a single step (maybe MPDCenter?) but it shouldn't be to hard to do yourself especially when you already set something up.

The trick is to recursively scan for type 1 lines while keeping a 'parent' matrix in mind. Then based on how these type 1 lines resolve (part or model) do one of two things:

If it's a part (resolved to LDraw location) copy the line to the output ldr while using the line's matrix multiplied with the parent matrix (order is important -> newLineMat = LineMat * parentMat, then go on with the next line.

If it's a non part (outside ldraw location) multiply the parent matrix with the line's matrix (newParentMat = LineMat * parentMat (keep the org parent matrix for the next line) and go recursively inside the referenced (sub)model using the resulting matrix as it's parent matrix.

While doing this you should handle submodels in the mpd like any other 'standalone' model. So don't go recursivly into them unless they are referenced from the main mpd model.

Hope this is somewhat clear/helps

ps I'm asuming the mpd only holds references to official parts and model only custom files. If not so you need to do more work to preserve non type 1 lines and exclude unofficial parts etc.
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#3
Thanks Roland for the prompt reply.

I took a look at MPDCenter - not heard of it before - but doesn't seem to do what I need.

I think I have to start at the 'deepest' nested model and work backwards ?

So if I start with

Model Depth 0
--Sub Model 1 (Depth 1)
----Sub Model 1a (Depth 2)
--Sub Model 2 (Depth 1)

The 1st step is to 'merge' Sub Model 1a (at Depth 2) with Sub Model 1 (at Depth 1)

So I end up with:

Model Depth 0
--Sub Model Depth1 (now including parts from Sub Model Depth 1a)
--Sub Model 2 (Depth 1)

The merging of X,Y,Z I can handle - its the matrix math where I struggle.

It's been a month or so since I looked at this last - now coming back to it for another go...

If the submodel is a single dat file (unlikely) then I can get it to work (I think) but if the submodel has multiple parts (very likely) these child parts are not transformed by the 'parent' line because they are potentially offset from the parent position. i.e. if you transformed each dat file in the submodel by the parent line you don't get the correct result....

I think this is because the parent line is effectively the rotation centre (or 'pseudo' origin) for the child model...
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#4
Rob Wrote:I think I have to start at the 'deepest' nested model and work backwards ?

It depends on what you want if you want a single flattened ldr containing the visual same model as the level 0 one it's best to start at top level and go recursively through all it's branches, this will automatically account for multiple references to the same submodel (e.g. model 1a could be referenced using a completely different position from model 3 or something). The merging you speak of will essentially be done like a zipper this way.

Rob Wrote:The merging of X,Y,Z I can handle - its the matrix math where I struggle.

You are essentially right about what you call a 'pseudo' origin cause the x y z in combination with the other 9 number makeup a transformation matrix which describe how to place/rotate the referenced part/model in the referring document.

So you have to use all 12 numbers in a single 4x4 matrix (see LDraw spec documents for more info on this), you don't need to handle them separately.

By multiplying these matrices with the ones of higher levels you adjust their transformation to the absolute space of the top level document. 'spitting' these new lines (with adjusted 12 numbers) into a new ldr results in a flattened version of the original set of ldr/mpd's.



As for the matrix math, depending on the program/script language you use multiplying two matrices is fairly simple, there are probably even default libraries for it. But you would only be needing a multiplying function which is little more then two for loops, source for those can be found all over the net.



You might also need to look deeper in the inner workings of MPD's to correctly handle the submodels of a single mpd file.
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#5
If you're willing to try to get the LDLoader portion of LDView to compile on your system, it could be fairly easily written:
  1. Use LDLoader to load the MPD file into an LDLMainModel object.
  2. Create a (recursive) function called flatten() that takes an already opened FILE*, an LDLModel* object, and a const float * matrix as its inputs.
  3. Pass the LDLMainModel object from step one, along with TCVector::getIdentityMatrix() into flatten(). (LDLMainModel is a subclass of LDLModel.)
  4. Inside flatten(), iterate through the first model->getActiveLineCount() file lines in the model using model->getFileLines() to get the array of lines.
  5. For each file line, check to see if it's a model line (type 1) (fileLine->getLineType() == LDLLineTypeModel)
  6. If it is a model line, create a local variable by typecasting from LDLFileLine* to LDLModelLine*.
  7. Call modelLine->getMatrix() to get the model line's matrix, then use TCVector::multMatrix(matrix, modelLineMatrix, newMatrix) to get the modified matrix (newMatrix is a local variable of type float[16]).
  8. Check to see if it's a part: modelLine->getModel()->isPart()
  9. If it's a part, write out a line to the output file as "1 modelLine->getColorNumber() newMatrix[0] newMatrix[1] newMatrix[2] newMatrix[4] newMatrix[5] newMatrix[6] newMatrix[8] newMatrix[9] newMatrix[10] modelLine->getModel()->getFilename()"
  10. If it's not a part, call flatten() with file, modelLine->getModel() and newMatrix.
  11. If the file line isn't a model line, ignore it.

The above could be improved. For example, you could support all line types, instead of just line type 1, but you'd have to very carefully avoid writing out the MPD-specific comments, and you'd have to have separate logic for each line type. Since I assume you want to just flatten an MPD that is made up of parts, the above algorithm should do the trick.

Note also that you don't have to use LDLoader from LDView to do this, but doing so would remove all the LDraw parsing requirements, since it would do all that. LDLoader is C++. If you're interested, send me an email that includes what OS (Windows, Mac, or Linux), and I'll try to get you up and running with LDLoader.
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#6
Hi Travis,

Thanks for the reply.

I'm going to take another look at the stuff I did a while back - I think I was close but not quite there and the code got pretty involved (at least for me). The reason for the original post was I didn't want to re-invent the wheel if someone had already done it somewhere that I could use.

FYI - I'm on Windows and using VB.net for my work.

I'll give it a new try based on your method outlined above. (I already have a class which does lots of stuff with Ldraw files, and VB.net has some matrix libraries which I have used before)

(Not sure how to PM you - your email is hidden...)

Rob (TCBUK)
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#9
Send email to the LDView email address, and it will get to me.
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#7
Interesting idea, indeed.

I need to have a look at my code in MPDCenter.

I am right that you like to have the models inlined until the parts appear, or do you like to have it broken down to quads only ? :-)

I go and try with the parts!
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#8
Hi Michael,

The order in which the parts appear is not important (I can sort them how I like later).

Starting from with a single MPD file, which may contain 'in-line' ldr files or links to 'external' ldr files (but in the same folder/directory as the source MPD File).

I want to end up with a single ldr file which contains all the parts for the complete model in the absolute position and rotation relative to 0,0,0 (not relative to any other part). So the final element of each line (line type 1) should be a .dat file which exists in the LDRAW parts folder.

Rob.
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#10
That is the same I thought about.

Please see my first result compared to the mpd content file.

I did not make much tests right now, so this function still needs to be processed.

I hope this is nearly similar to what you are looking for.


Attached Files
.ldr   20006 - Clone Turbo Tank.ldr (Size: 191.98 KB / Downloads: 0)
.mpd   20006 - Clone Turbo Tank.mpd (Size: 13.07 KB / Downloads: 0)
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#11
Excellent ! That's looking good as far as I can see.

Could you try the attached model (which I originally downloaded from this forums MOC section).

Is how your doing this something you could put into a command line utility ?

e.g. MAKELDR.EXE input.mpd output.ldr

Many thanks.

Rob


Attached Files
.ldr   Jim_DeVona_StarFighter_5.ldr (Size: 14.41 KB / Downloads: 0)
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#12
OK hold the front page - I think I have cracked it !!!

Attached is my 'flattened' version of the file I attached in my previous post (only line type 1's included)

(When I looked at this a couple of months back I literally spent a week solid trying to get this to work - amazing what coming back afresh can do - and Travis's step by step method list was also the catalyst which got it working - so thanks Travis).

The code (for those who are interested in these things) is as follows (the Ldrawpart is my own class - not included here).

Function Flatten(ByVal cModelFile As String, ByVal oParentMatrix As Windows.Media.Media3D.Matrix3D)

Dim cModelData As String = IO.File.ReadAllText(cModelFile)
Dim aLines As Array = Split(RemoveTrailingLineFeeds(cModelData), vbCrLf)
Dim oPart As LDrawPart

For Each cLine In aLines
oPart = New LDrawPart(cLine, ExtractPath(cModelFile) & "\")
If oPart.LineType = 1 Then
If LCase(RightStr(oPart.DatFile, 4)) = ".ldr" Then
Flatten(ExtractPath(cModelFile) & "\" & oPart.DatFile, oPart.Matrix3d)
Else
Dim oNewMatrix As Matrix3D = Matrix3D.Multiply(oPart.Matrix3d, oParentMatrix)
cCombinedData = cCombinedData & oPart.LineType & " " & _
oPart.Colour & " " & _
oNewMatrix.OffsetX & " " & _
oNewMatrix.OffsetY & " " & _
oNewMatrix.OffsetZ & " " & _
oNewMatrix.M11 & " " & _
oNewMatrix.M21 & " " & _
oNewMatrix.M31 & " " & _
oNewMatrix.M12 & " " & _
oNewMatrix.M22 & " " & _
oNewMatrix.M32 & " " & _
oNewMatrix.M13 & " " & _
oNewMatrix.M23 & " " & _
oNewMatrix.M33 & " " & _
oPart.DatFile & vbCrLf
End If
Else
cCombinedData = cCombinedData & cLine & vbCrLf
End If
Next

IO.File.WriteAllText(ExtractPath(cModelFile) & "\flattened.ldr", cCombinedData)

End Function


(This function assumes all 'in-line' ldr files in the MPD file have already been extracted as seperate files (in the same folder/directory) as the 'base' file - that's easy to do).

This is SO much simpler that what I was trying before !

HOORAY ITS CHRISTMAS !


Attached Files
.ldr   flattened.ldr (Size: 18.54 KB / Downloads: 0)
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#13
Update:

All working well except with models which feature a custom rotation point(s) such as

0 ROTATION CENTER -30 -2 0 1 "Custom"
0 ROTATION CONFIG -2 0

I assume the -30 -2 0 is the X,Y,Z point to rotate around - applying to any following parts... but what is the 4th numeric element ?
Also - what is the significance of the ROTATION CONFIG numbers ?

(I have googled for this but can't find any reference).

Rob.
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#14
What do you expect should happen with that line?

If you want to have that rotation point also in your flatterend version with the same functionality than in the structured version before, then you also need to apply the changes to that values. IMHO

Edit:
MLCad produces for every model in an mpd content file these two lines. By inlining these models into the main model you will get lots of 0 ROTATION lines. I have not yet checked how MLCad will work with more than one entry and which (first or last) will be used then. So to have those rotation point working also in the flatterened file will be difficult in my eyes. At present my export routine simply ingnores these 0 ROTATION line during inlining process.

By the way:
I saw in your code that you rely on the extension of the file. We just had an discussion here that this is not a good idea.
Official parts are forced to carry the extension '.dat'. But that is all we surely know. So it might be that a file with the extension '.ldr' has mpd content and should be processed like that.
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#15
Hi Michael,

Thanks for the reply.

I'm trying to achive an LDR file which has only type 1 lines ideally. Any custom rotations should be 'incorporated' into the flatten function so that the pieces are at their absolution position and any translation/rotation values in the ldraw line entry are related to 0,0,0 not to any other 'custom' rotation point.

Thanks for the note that the 'submodel' might be an MPD file also - I'll bear that in mind.

FYI - I need the LDR files in this 'standalone' format for an animation function which I use for creating 'build' animations of Lego models - it works fine with 'straight' LDR files but not with MPD files - so I'm trying to create a routine that will take any MPD file and 'flatten' it into a 'simple as possible' LDR file ready for processing by my animation function.

(The custom rotation is not a huge problem as not that many models I've seen feature it - at anything other than the default values - but for completeness I would like to deal with it correctly).

Rob (TCBUK)
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#16
Code:
FYI - I need the LDR files in this 'standalone' format for an animation function which I use for creating 'build' animations of Lego models - it works fine with 'straight' LDR files but not with MPD files - so I'm trying to create a routine that will take any MPD file and 'flatten' it into a 'simple as possible' LDR file ready for processing by my animation function.
Do you have already something to show :-)

The next version of MPDCenter will have this 'flatten' function. Currently I am working on referenced mpd content files.
I am not sure to make a command line tool as derivation. Before you do the flattening you should have all the files needed in the mpd, and that is sometimes not the case. At this point MPDCenter can help if you have the required part somewhere on your disk.
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#18
For some samples of my work to date (using non-mpd files so far - or ones that I've have got to work with out 'flattening') please visit...

http://www.thecreativebrick.co.uk
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#17
I don't think I understand. If you just want to output an LDR file with all type 1 lines, you should be able to completely ignore the rotation points, shouldn't you? They may be used by editors like MLCAD to aid in rotating the sub-models inside an MPD, but that just changes the way the MLCAD re-calculates the matrix that refers to the file. They are completely ignored by renderers.
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#19
I've attached the model which my flatten function fails to work correctly on.

Original model found here: http://lego.bldesign.org/models/?m=cormorant

(I think it's a really fab design BTW).

Travis - I don't think the MLCAD custom rotation lines should affect anything either, it may be something else which is causing the problem with this particular model.

Michael - could you try this with your flatten function and see if it works ?

There maybe something odd about this particular model file (apart from the custom rotation lines) which is throwing something.

Rob (TCBUK)


Attached Files
.mpd   cormorant.mpd (Size: 43.39 KB / Downloads: 0)
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#20
No problem on this side. Works like expected.

I remember that I also had lots of days spend in finding all necessary code to do it right Smile


Attached Files
.ldr   cormorant.ldr (Size: 116.39 KB / Downloads: 0)
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#21
As if often the case (!) - the mistake was mine - not the model.

Error in my code meant that parent matrix was not being applied to sub-model lines if the sub-model line was a reference to another sub-model.

Courmorant model now flattens correctly (my flattened version attached).


Attached Files
.ldr   flattened.ldr (Size: 122.68 KB / Downloads: 0)
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#22
Hi, I'd just like to add my 0.02 € to this thread,
to avoid confusion.
The 0 ROTATION element is just MLCad specific,
and it has nothing to do with MPDs or how they rotate the files contained within them.
It only tells MLCad WHERE to put the rotation point for the GUI,
has nothing to do with the rotation point around which the part gets rotated when used in its parent mpd!
Make sure you do _NOT_ use this line for the rotation when inlining into a single ldr...
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#23
I hope it's not a problem that I bump this very old topic, but I'm also interested in a .mpd to .ldr converter.
Is there any converter available?
I suppose the topic starter got something to work, because he said he needed such a converter for animations and he has a lot of animations on his website.
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#24
Maybe you should give MPDCenter a try Smile
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#26
Use LeoCAD, it now has full MPD support and can easily export the main model assembly to ldr, hassle free.
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#25
Give the attached Python script a try (test example included) - I implemented it because I'm trying to add a motor to the 42005 Lego Monster Truck following the MPD file from rebrickable, but I couldn't find any tool to give me a flat LDR file so I can use tools like Bricksmith to bisect the model since the steps provided in the MPD file are pretty useless when you're trying to figure out how to build this thing...

Supports nested LDR references, but does NOT support references to other MPD files.
Works only on one file at a time.

How to use:
unzip, then you should have a mpd2ldr.py file - that file must be executable.
Now just call "./mpd2ldr.py filename.mpd" and the output will be filename.ldr
Has to be used from the command line (I've tried it on a Mac only)

I hope it works for you, and please forgive me if I don't provide support Smile


Attached Files
.mpd   lg42005_motorized.mpd (Size: 21.62 KB / Downloads: 1)
.zip   mpd2ldr.zip (Size: 2.32 KB / Downloads: 4)
Reply
Re: Export of .mpd to single 'stand-alone' .ldr file ?
#27
Well...
I see all kind of scary rocket-science type of answers in this thread.
I personally have always done the MPD to LDR conversion directly in MLCAD using the export menu.
In case you have multiple steps it generates an LDR file for each step, but you just take the last step (biggest file size) and you got your converted file.
As simple as that :-)

- Mattia
Reply
« Next Oldest | Next Newest »



Forum Jump:


Users browsing this thread: 1 Guest(s)
Forum Jump:


Users browsing this thread: 1 Guest(s)