To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.cadOpen lugnet.cad in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 CAD / 11576
Subject: 
Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 17 Jun 2004 12:55:21 GMT
Viewed: 
1321 times
  
Hi--

Does anybody know a quick way to do a mirror image of an LDraw model?  For
example, a castle that I'm working on has a left and right tower that are mirror
images (not rotations) of each other (and the rear corner  towers are mirrors of
the front ones).  Rather than make 4 different models, is there a quick way to
flip my model into the four different towers?

Thanks for the help!
Carl


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 17 Jun 2004 13:33:52 GMT
Viewed: 
1336 times
  
In lugnet.cad, Carl Nelson wrote:
Hi--

Does anybody know a quick way to do a mirror image of an LDraw model?  For
example, a castle that I'm working on has a left and right tower that are mirror
images (not rotations) of each other (and the rear corner  towers are mirrors of
the front ones).  Rather than make 4 different models, is there a quick way to
flip my model into the four different towers?

Thanks for the help!
Carl

I usually use submodels save your tower as a tower-left or something.  you have
to go thruogh each part and change either the x or z value to the opposite value
(ex. if the X is -300 change to 300)  then rotate each part 180 degrees.  There
are also a lot of left and right parts which need to be swaped.

or in povray you can use scale with a negative value (ex. scale<-1,0,0> ) this
will mirror around the x axis.

There is no easy way.

Steve


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 17 Jun 2004 14:31:27 GMT
Viewed: 
1469 times
  
In lugnet.cad, Steve Krass wrote:
In lugnet.cad, Carl Nelson wrote:
Hi--

Does anybody know a quick way to do a mirror image of an LDraw model?  For
example, a castle that I'm working on has a left and right tower that are mirror
images (not rotations) of each other (and the rear corner  towers are mirrors of
the front ones).  Rather than make 4 different models, is there a quick way to
flip my model into the four different towers?

Thanks for the help!
Carl

I usually use submodels save your tower as a tower-left or something.  you have
to go thruogh each part and change either the x or z value to the opposite value
(ex. if the X is -300 change to 300)  then rotate each part 180 degrees.  There
are also a lot of left and right parts which need to be swaped.

or in povray you can use scale with a negative value (ex. scale<-1,0,0> ) this
will mirror around the x axis.

There is no easy way.

The way I usually do this is clunky, but it basically works.  It also requires a
little familiarity with MS Excel and some kind of text editor, as well as  an
understanding of the LDraw DAT-file format.

Create a backup of the MOC file.  Open the backup file in MS Excel, in "space
delimited" format.  For simplicity, let's assume the following:

1.  Any title info within the DAT file is omitted for this operation
2.  The ZERO character in line one at the start of the file appears in
    cell A1 in the Excel spreadsheet
3.  The first linetype 1 statement begins in cell B2 in the Excel spreadsheet

Here's how I do what I do when I do it:

For simple mirroring of the parts from left-to-right.  This only works for parts
oriented along the X, Y, and Z axes.  If parts are rotated at odd angles (like
30 degrees, or whatever), then this won't quite work, but it should get you
started.

1.  Identify which lines contain the parts of the model that you want to
    mirror (let's say lines 2 through 50).
2.  Copy these lines to another location in the file (let's say 51 through 99)
3.  Set cell D51 to equal "-D2"
4.  Select cell D51 and "copy"
5.  Select cells D52 through D99
6.  Paste

At this point the parts now exist in their original locations and at the
corresponding mirrored locations, but the mirrored locations are not oriented
correctly.  To correct the orientation, do the following:

1.  Select cell D51 and "copy"
2.  Select cells G51 through G99
3.  Paste

This will invert the orientation left-to-right and vice versa.

To perform the same mirroring front-to-back, perform the same steps as above,
but instead of using columns D and G, you'd use columns F and O, respectively.

To perform the same mirroring up-to-down, perform the same steps as above, but
instead of using columns D and G, you'd use columns E and K, respectively.

After you have made all of your changes, save the Excel spreadsheet in
tab-delimited format, and use the .DAT extension in the file name, such as
"MOC1.dat"

At this point, the body of the MOC1.dat file has a bunch of tab characters where
there should be spaces.  Open the MOC1.dat file in a text-based editor that
allows you to do bulk find-replace operations, and replace each of the "tab"
characters with a single space.

Save the file and open it in your LDraw platform of choice to view the results.

Here's a Known Shortcoming of this method:  it doesn't automatically accommodate
linetype zero statements that appear within the body of the DAT file, nor does
it automatically accommodate METASTATEMENTS.  You'll need to tweak those
manually if they present a problem.

I apologize if my explanation is unclear, but I can attest to the effectiveness
of the method, because I've used it dozens of times for model files and for new
partfiles.  Let me know if you'd like clarification on any point.

Best of luck!

Dave!


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 17 Jun 2004 15:20:23 GMT
Viewed: 
1552 times
  
In lugnet.cad, Dave Schuler wrote:
In lugnet.cad, Steve Krass wrote:
In lugnet.cad, Carl Nelson wrote:
Does anybody know a quick way to do a mirror image of an LDraw
model?  For example, a castle that I'm working on has a left and
right tower that are mirror images (not rotations) of each other
(and the rear corner towers are mirrors of the front ones).
Rather than make 4 different models, is there a quick way to flip
my model into the four different towers?

I usually use submodels save your tower as a tower-left or
something.  you have to go thruogh each part and change either the
x or z value to the opposite value (ex. if the X is -300 change to
300) then rotate each part 180 degrees.  There are also a lot of
left and right parts which need to be swaped.

or in povray you can use scale with a negative value
(ex. scale<-1,0,0> ) this will mirror around the x axis.

There is no easy way.

The way I usually do this is clunky, but it basically works.  It
also requires a little familiarity with MS Excel and some kind of
text editor, as well as an understanding of the LDraw DAT-file
format.

Create a backup of the MOC file.  Open the backup file in MS Excel,
in "space delimited" format.  For simplicity, let's assume the
following:

1.  Any title info within the DAT file is omitted for this operation
2.  The ZERO character in line one at the start of the file appears in
    cell A1 in the Excel spreadsheet
3.  The first linetype 1 statement begins in cell B2 in the Excel
    spreadsheet

Here's how I do what I do when I do it:

For simple mirroring of the parts from left-to-right.  This only
works for parts oriented along the X, Y, and Z axes.  If parts are
rotated at odd angles (like 30 degrees, or whatever), then this
won't quite work, but it should get you started.

1.  Identify which lines contain the parts of the model that you
    want to mirror (let's say lines 2 through 50).
2.  Copy these lines to another location in the file (let's say 51
    through 99)
3.  Set cell D51 to equal "-D2"
4.  Select cell D51 and "copy"
5.  Select cells D52 through D99
6.  Paste

At this point the parts now exist in their original locations and at
the corresponding mirrored locations, but the mirrored locations are
not oriented correctly.  To correct the orientation, do the
following:

1.  Select cell D51 and "copy"
2.  Select cells G51 through G99
3.  Paste

This will invert the orientation left-to-right and vice versa.

To perform the same mirroring front-to-back, perform the same steps
as above, but instead of using columns D and G, you'd use columns F
and O, respectively.

To perform the same mirroring up-to-down, perform the same steps as
above, but instead of using columns D and G, you'd use columns E and
K, respectively.

After you have made all of your changes, save the Excel spreadsheet
in tab-delimited format, and use the .DAT extension in the file
name, such as "MOC1.dat" • L
At this point, the body of the MOC1.dat file has a bunch of tab
characters where there should be spaces.  Open the MOC1.dat file in
a text-based editor that allows you to do bulk find-replace
operations, and replace each of the "tab" characters with a single
space.

Save the file and open it in your LDraw platform of choice to view
the results.

Here's a Known Shortcoming of this method: it doesn't automatically
accommodate linetype zero statements that appear within the body of
the DAT file, nor does it automatically accommodate METASTATEMENTS.
You'll need to tweak those manually if they present a problem.

I apologize if my explanation is unclear, but I can attest to the
effectiveness of the method, because I've used it dozens of times
for model files and for new partfiles.  Let me know if you'd like
clarification on any point.

This is silly.  Just put the structure you want to mirror in a
subfile and do this.

  1 0 0 0 0 1 0 0 0 1 0 0 0 1 subfile.ldr
  1 0 320 0 0 -1 0 0 0 1 0 0 0 1 subfile.ldr

You can do it in ldglite using the scale by (-1,1,1) command (just
like in POV).  Then use your favorite CAD program to position the part
and it's mirror wherever you want them.  If you like, inline them
both.  That'll generate pictures that look correct.  The only problem
will be if you use the LDR file to generate an inventory list and you
have distinct left and right parts like wing plates.

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 17 Jun 2004 15:27:25 GMT
Viewed: 
1551 times
  
In lugnet.cad, Don Heyse wrote:
In lugnet.cad, Carl Nelson wrote:
Does anybody know a quick way to do a mirror image of an LDraw
model?

Just put the structure you want to mirror in a
subfile and do this.

  1 0 0 0 0 1 0 0 0 1 0 0 0 1 subfile.ldr
  1 0 320 0 0 -1 0 0 0 1 0 0 0 1 subfile.ldr

Oops, wrong color.  That should be

  1 16 0 0 0 1 0 0 0 1 0 0 0 1 subfile.ldr
  1 16 320 0 0 -1 0 0 0 1 0 0 0 1 subfile.ldr

just in case...

Enjoy,

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 17 Jun 2004 15:39:49 GMT
Viewed: 
1622 times
  
In lugnet.cad, Don Heyse wrote:

I apologize if my explanation is unclear, but I can attest to the
effectiveness of the method, because I've used it dozens of times
for model files and for new partfiles.  Let me know if you'd like
clarification on any point.

This is silly.  Just put the structure you want to mirror in a
subfile and do this.

  1 0 0 0 0 1 0 0 0 1 0 0 0 1 subfile.ldr
  1 0 320 0 0 -1 0 0 0 1 0 0 0 1 subfile.ldr

You can do it in ldglite using the scale by (-1,1,1) command (just
like in POV).  Then use your favorite CAD program to position the part
and it's mirror wherever you want them.  If you like, inline them
both.  That'll generate pictures that look correct.  The only problem
will be if you use the LDR file to generate an inventory list and you
have distinct left and right parts like wing plates.

Won't that cause all of the LEGO logo on all of the studs in the mirrored parts
to be reversed?  I thought that part of the point of the question was to avoid
that.  I think that measures are being taken to correct the mirrored-logo issue,
but I'd prefer a more organic solution instead.  YMMV.

Also, no kidding you can create a sub-file and do a matrix switcheroo to mirror
it, but what if you want to have slight modifications to each of the four castle
towers?  Your method won't help at all in that case, unless you wanted to create
four separate sub-files, altering each as desired, and then inlining them, but
that doesn't seem an appreciably better solution that what I proposed.  Using my
method, the whole mirrored tower is accessible for modification, and you don't
have to worry about mirroring any complex structures, since you'll be building
them in true orientation.

While I'm at it, your method will certainly work to an extent, but the method I
described has the benefit of functioning without inlined sub-files, and it works
just as well it partfiles or model files.

If this method seems silly to you, may I suggest that you not use it?

Dave!


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 17 Jun 2004 15:52:23 GMT
Viewed: 
1714 times
  
In lugnet.cad, Dave Schuler wrote:
  [snip]
If this method seems silly to you, may I suggest that you not use it?

Bad choice of words "silly".  Sorry about that, but he asked for a
"quick" way to do it.  He used the word "quick" twice in fact.  But
everyone seemed intent on providing a thorough, but complex method
without first telling the quick and dirty way.  There are plenty of
newbies out there who don't know it.

Have fun,

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 17 Jun 2004 16:25:30 GMT
Viewed: 
1727 times
  
In lugnet.cad, Don Heyse wrote:
In lugnet.cad, Dave Schuler wrote:
  [snip]
If this method seems silly to you, may I suggest that you not use it?

Bad choice of words "silly".  Sorry about that, but he asked for a
"quick" way to do it.  He used the word "quick" twice in fact.  But
everyone seemed intent on providing a thorough, but complex method
without first telling the quick and dirty way.  There are plenty of
newbies out there who don't know it.

Fair enough--I guess "quick" is in the eye of the beholder.  8^)

Dave!


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 17 Jun 2004 19:21:53 GMT
Viewed: 
1697 times
  
In lugnet.cad, Dave Schuler wrote:
For simple mirroring of the parts from left-to-right.  This only works for parts
oriented along the X, Y, and Z axes.  If parts are rotated at odd angles (like
30 degrees, or whatever), then this won't quite work, but it should get you
started.
(snip)

Thanks for the responses--they were very helpful.  I found the disadvantage to
Don's rotation matrix method to be that when it's used the mouse commands in
MLCad are reversed, i.e., dragging the part left moves it right--but it sure
worked great for a quick way to show the assembled model correctly.

Dave, I tried your method in Excel and it appears to work with some caveats,
though I don't really understand the column mappings:

For left-to-right, you said to use columns D and G--that's corresponding to the
Y position and the B rotation parameter.  Shouldn't that be the X position and C
parameter?

Parts such as slopes & 2 x 2 corners aren't in their correct orientation--any
tips on how to get those right?

(Actually, is there a tutorial on the rotation matrix anywhere?  That might
answer all my questions in one.)

Thanks!
Carl


Special: 
[DAT] (requires LDraw-compatible viewer)
Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 17 Jun 2004 19:52:27 GMT
Viewed: 
1890 times
  
In lugnet.cad, Carl Nelson wrote:
In lugnet.cad, Dave Schuler wrote:
For simple mirroring of the parts from left-to-right.  This only works for parts
oriented along the X, Y, and Z axes.  If parts are rotated at odd angles (like
30 degrees, or whatever), then this won't quite work, but it should get you
started.

Dave, I tried your method in Excel and it appears to work with some caveats,
though I don't really understand the column mappings:

For left-to-right, you said to use columns D and G--that's corresponding to the
Y position and the B rotation parameter.  Shouldn't that be the X position and C
parameter?

You know, I think you're correct about that.  I think I'm the last person who
still uses LEdit as his primary LDraw platform, and for reasons of my own I
always orient my parts and models rotated 90 degrees relative to the true LDraw
standard orientation.

Maybe I should give a specific example of the default orientation, with the 2x4
brick at cursor position x=100, y=0, and z=-10.  The letters correspond to the
Excel columns:

A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P

    1   16  100 0  -10  1   0   0   0   1   0   0   0   1   3001.DAT

The mirrored left-to-right, the line would read this way:

A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P

    1   16  100 0  -10 -1   0   0   0   1   0   0   0  -1   3001.DAT


If we're ignoring odd angles (30 degrees, or whatever) then the left-and-right
orientation will (should) always be governed by the G and O columns, and the
position will be goverend by columns D, E, and F.
.  To mirror a part left-to-right, change the D, F, G, and O columns in the
mirror part to the negative values of the same columns in the original part.

I think that this corrects the omission of my earlier explanation.  Depending on
your level of comfort with Excel (and depending also on the usefulness of my
explanation) you should be able to tweak all of the necessary cells fairly
easily.

Parts such as slopes & 2 x 2 corners aren't in their correct orientation--any
tips on how to get those right?

Sorry again about the omission--try it again with this new information that I
forgot to include before, and let me know if it works for you.

(Actually, is there a tutorial on the rotation matrix anywhere?  That might
answer all my questions in one.)

That's a fine question.  There are two very basic discussions of
orientation-in-space here:

http://www.ldraw.org/files/LDRAW.TXT
http://www.ldraw.org/files/LEDIT.TXT

Not bad as starting points, but they don't quite answer your question, either.

Good luck!

Dave!


Special: 
[DAT] (requires LDraw-compatible viewer)
Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 17 Jun 2004 20:23:36 GMT
Viewed: 
2194 times
  
In lugnet.cad, Dave Schuler wrote:
In lugnet.cad, Carl Nelson wrote:
In lugnet.cad, Dave Schuler wrote:
For simple mirroring of the parts from left-to-right.  This only works for parts
oriented along the X, Y, and Z axes.  If parts are rotated at odd angles (like
30 degrees, or whatever), then this won't quite work, but it should get you
started.

Dave, I tried your method in Excel and it appears to work with some caveats,
though I don't really understand the column mappings:

For left-to-right, you said to use columns D and G--that's corresponding to the
Y position and the B rotation parameter.  Shouldn't that be the X position and C
parameter?

You know, I think you're correct about that.  I think I'm the last person who
still uses LEdit as his primary LDraw platform, and for reasons of my own I
always orient my parts and models rotated 90 degrees relative to the true LDraw
standard orientation.

Maybe I should give a specific example of the default orientation, with the 2x4
brick at cursor position x=100, y=0, and z=-10.  The letters correspond to the
Excel columns:

A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P

    1   16  100 0  -10  1   0   0   0   1   0   0   0   1   3001.DAT

The mirrored left-to-right, the line would read this way:

A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P

    1   16  100 0  -10 -1   0   0   0   1   0   0   0  -1   3001.DAT

Dumb, dumb, dumb.  To be a true "mirror" as you've requested, the second example
should have read this way:

A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P

     1   16 -100 0  -10 -1   0   0   0   1   0   0   0  -1   3001.DAT

The way I originally posted it, the 3001 brick would be flipped left-to-right,
but it would be at the same location as the non-flipped brick.

Sorry about that.

Dave!


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 17 Jun 2004 23:49:56 GMT
Viewed: 
1645 times
  
In lugnet.cad, Dave Schuler wrote:
Won't that cause all of the LEGO logo on all of the studs in the mirrored parts
to be reversed?  I thought that part of the point of the question was to avoid

If this bothers you, a partial solution is here:

http://news.lugnet.com/cad/dev/?n=9067

While the results from running the program aren't really appropriate for
distribution to others, you can at least do your own POV renderings (as long as
you don't use -lgeo).  Additionally, the stud logos should always look correct
in both LDView and LDGLite, since both programs automatically detect mirrored
studs and un-mirror them.

--Travis


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Fri, 18 Jun 2004 00:31:13 GMT
Viewed: 
1700 times
  
In lugnet.cad, Don Heyse wrote:
In lugnet.cad, Dave Schuler wrote:
  [snip]
If this method seems silly to you, may I suggest that you not use it?

Bad choice of words "silly".  Sorry about that, but he asked for a
"quick" way to do it.  He used the word "quick" twice in fact.  But
everyone seemed intent on providing a thorough, but complex method
without first telling the quick and dirty way.  There are plenty of
newbies out there who don't know it.

Have fun,

Don

I didn't necessarily mean quick, I meant easy.  Hey, I'm lazy. ;-)

I like both answers because you gave me what I needed to know to accomplish the
task quickly, Dave gave me what I needed to know to understand what I'm doing!

Carl


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Fri, 18 Jun 2004 00:38:38 GMT
Viewed: 
2397 times
  
In lugnet.cad, Dave Schuler wrote:
Dumb, dumb, dumb.  To be a true "mirror" as you've requested, the second example
should have read this way:

A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P

     1   16 -100 0  -10 -1   0   0   0   1   0   0   0  -1   3001.DAT

The way I originally posted it, the 3001 brick would be flipped left-to-right,
but it would be at the same location as the non-flipped brick.

Sorry about that.


Wouldn't that still be a 180 degree rotation rather than a flip, since

           -1  0  0
(x y z) *   0  1  0 = (-x y -z)
            0  0 -1

?

Or am I laying out my rotation matrix incorrectly (is the first line a b c or a
d g)?

Sorry for all the stupid questions, I'm still trying to dredge my linear algebra
out of the dark recesses of my memory.

Thanks,
Carl


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Fri, 18 Jun 2004 00:47:26 GMT
Viewed: 
2493 times
  
In lugnet.cad, Carl Nelson wrote:
Or am I laying out my rotation matrix incorrectly (is the first line a b c or a
d g)?

I found the answer to this
(http://www.ldraw.org/modules.php?op=modload&name=News&file=article&sid=45), the
first column should be a d g.  My poor layout doesnn't change the rotation
matrix (I think).

Carl


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Fri, 18 Jun 2004 00:49:38 GMT
Viewed: 
2507 times
  
In lugnet.cad, Carl Nelson wrote:
I found the answer to this
(http://www.ldraw.org/modules.php?op=modload&name=News&file=article&sid=45), the
first column should be a d g.  My poor layout doesnn't change the rotation
matrix (I think).

Darn it, I meant the first ROW.  (Doesn't show that I have a math degree, eh?
;-)

Carl


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Fri, 18 Jun 2004 14:19:22 GMT
Viewed: 
2477 times
  
In lugnet.cad, Carl Nelson wrote:
In lugnet.cad, Dave Schuler wrote:
Dumb, dumb, dumb.  To be a true "mirror" as you've requested, the second example
should have read this way:

A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P

     1   16 -100 0  -10 -1   0   0   0   1   0   0   0  -1   3001.DAT

The way I originally posted it, the 3001 brick would be flipped left-to-right,
but it would be at the same location as the non-flipped brick.

Sorry about that.


Wouldn't that still be a 180 degree rotation rather than a flip, since

           -1  0  0
(x y z) *   0  1  0 = (-x y -z)
            0  0 -1

?

Or am I laying out my rotation matrix incorrectly (is the first line a b c or a
d g)?

Sorry for all the stupid questions, I'm still trying to dredge my linear algebra
out of the dark recesses of my memory.

When you ask a stupid question, I'll let you know!  8^)

You're right--it would rotate the brick 180 degrees, but I think that's
necessary sometimes (like for the 2x2 slope bricks mirrored left-to-right).  But
you're also right that this isn't desireable in the case of bricks mirrored
front-to-back.  That's where my clunky explanation really breaks down.

You'd probably want to avoid a "flip," because that would cause the stud-logos
to be reversed.  I think basically you'll need to rotate some bricks 180 degrees
for the second tower, and you'll simply move other bricks (along the axes from
the first tower's location to the second, without rotating the brick along the
way).

Sadly, I can't help you with the formal matrix rotation or linear algebra--my
understanding of all of this comes from picking at LDraw parts until I get what
I'm looking for...

The more I look at this, the more I see what Dan was saying--this is a
cumbersome method!

Dave!


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Fri, 18 Jun 2004 16:00:47 GMT
Viewed: 
2593 times
  
In lugnet.cad, Dave Schuler wrote:
You're right--it would rotate the brick 180 degrees, but I think that's
necessary sometimes (like for the 2x2 slope bricks mirrored left-to-right).  But
you're also right that this isn't desireable in the case of bricks mirrored
front-to-back.  That's where my clunky explanation really breaks down.

You'd probably want to avoid a "flip," because that would cause the stud-logos
to be reversed.  I think basically you'll need to rotate some bricks 180 degrees
for the second tower, and you'll simply move other bricks (along the axes from
the first tower's location to the second, without rotating the brick along the
way).

Now that I've done that, I agree with you.  The true proper thing to do is to
adjust the rotation matrix of all parts by

            -a  d -g
(x, y, z) * -b  e -h = (-ax-by-cz, dx+ey+fz, -gx-hy-iz)
            -c  f -i

and create a list of exceptions that would be a rotation matrix plus a
translation, for example a 2 x 2 corner reflected on a horizontal axis should be
rotated by:

0  0 -1
0  1  0
-1  0  0

giving (x' = -z, y' = y, z' = -x)

and then translated in X and Z axes to put it in the right place.

Basically that would mean that any part having a rotation point not at its
geometric center would need a custom rotation and translation.

Sadly, I can't help you with the formal matrix rotation or linear algebra--my
understanding of all of this comes from picking at LDraw parts until I get what
I'm looking for...

Don't worry--I actually have a math degree and did most of my work in linear
algebra & analytical geometry and, um, it took far longer to understand this
than I care to admit...

The more I look at this, the more I see what Dan was saying--this is a
cumbersome method!

Ah, it's not too bad, especially when I did my program to automate it.  It has
shortcomings, but it works for the majority and the rest is merely exception
processing.

Carl


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Fri, 18 Jun 2004 16:24:38 GMT
Viewed: 
2863 times
  
n lugnet.cad, Carl Nelson wrote:
The true proper thing to do is to adjust the rotation matrix of all
parts by

            -a  d -g
(x, y, z) * -b  e -h = (-ax-by-cz, dx+ey+fz, -gx-hy-iz)
            -c  f -i

and create a list of exceptions that would be a rotation matrix plus
a translation, for example a 2 x 2 corner reflected on a horizontal
axis should be rotated by:

0  0 -1
0  1  0
-1  0  0

giving (x' = -z, y' = y, z' = -x)

and then translated in X and Z axes to put it in the right place.

Basically that would mean that any part having a rotation point not
at its geometric center would need a custom rotation and
translation.

Sadly, I can't help you with the formal matrix rotation or linear
algebra--my understanding of all of this comes from picking at
LDraw parts until I get what I'm looking for...

Don't worry--I actually have a math degree and did most of my work
in linear algebra & analytical geometry and, um, it took far longer
to understand this than I care to admit...

The more I look at this, the more I see what Dan was saying--this
is a cumbersome method!

Ah, it's not too bad, especially when I did my program to automate
it.  It has shortcomings, but it works for the majority and the rest
is merely exception processing.

Take a peek at the MLCAD.INI file for minifig posing.  Could you
use a config file like this to handle the exceptions?  I'd imagine
if you pick one axis for mirroring that works best with most parts,
(I think Travis said most were symmetric across the Z axis?) then
you could give a rotation matrix for the exceptions to make them
line up correctly.  Then to get a mirror over another axis you
mirror over the standard axis and and apply a rotation to the
results.

It'd be really nice to create a MIRROR.INI file, put it in the ldraw
directory and keep it updated with the parts.  Then if you could put
some wrappers around your program to allow it to be used as an MLCAD
generator and an LDDP plugin, that'd be fantastic.

Have you considered making the source code available?

Enjoy,

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Fri, 18 Jun 2004 16:50:31 GMT
Viewed: 
2921 times
  
In lugnet.cad, Don Heyse wrote:
Ah, it's not too bad, especially when I did my program to automate
it.  It has shortcomings, but it works for the majority and the rest
is merely exception processing.

Take a peek at the MLCAD.INI file for minifig posing.  Could you
use a config file like this to handle the exceptions?  I'd imagine
if you pick one axis for mirroring that works best with most parts,
(I think Travis said most were symmetric across the Z axis?) then
you could give a rotation matrix for the exceptions to make them
line up correctly.  Then to get a mirror over another axis you
mirror over the standard axis and and apply a rotation to the
results.

Oh yeah, the other exception would be a part substitution, like
left minifig arm for right arm, or left wing plates for right wing
plates.

But watch out, some folks might object to substituting left-wing
for right-wing of anything.  ;^)

It'd be really nice to create a MIRROR.INI file, put it in the ldraw
directory and keep it updated with the parts.  Then if you could put
some wrappers around your program to allow it to be used as an MLCAD
generator and an LDDP plugin, that'd be fantastic.

Have you considered making the source code available?

Enjoy,

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Fri, 18 Jun 2004 17:52:59 GMT
Viewed: 
3052 times
  
In lugnet.cad, Don Heyse wrote:
In lugnet.cad, Don Heyse wrote:
Talking to myself...

Here's what I'm talking about.  Completely ripped off from the
MLcad.ini file.

  http://ldglite.sf.net/mirror.ini

That one contains an entry every part in my parts.lst file.  It
needs to have the changes made for the exceptions, but here's
how it starts.

;
; Mirror.ini
;
; ============================================================================
; This file is read by subfile mirror programs
; ============================================================================
; Lines beginning with ; are comments ...
; Empty lines are ignored

; This file contains information used to mirror a subfile across the Z axis.
; Many parts are symmetric across the Z axis and can be mirrored by simply
; negating the Z coordinate of the part in the subfile.
; Other parts need additional rotation, translation, and possibly substitution.
; This file tells what to do for those exceptional parts.
;
; Each line has the following format:
; PARTNAME MIRRORPART <Flags> <Matrix> <Offset>
; <PARTNAME> The name of the part file
; <MIRRORPART> The file name of the substutute part.
;              (It's the same as PARTNAME if no substitution is required.
; <Flags> always 0 reserved for future use
; <Matrix> a rotation matrix a11 a12 a13 ... a33 for optimal appearance at
;          0 degree rotation angle
; <Offset> The offset of the part to be in place
;

[MIRRORSETTINGS]
2546.DAT            2546.DAT            0  1 0 0 0 1 0 0 0 1  0 0 0
2546P01.DAT         2546P01.DAT         0  1 0 0 0 1 0 0 0 1  0 0 0
6029A.DAT           6029A.DAT           0  1 0 0 0 1 0 0 0 1  0 0 0


Special: 
[DAT] (requires LDraw-compatible viewer)
Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Fri, 18 Jun 2004 19:59:25 GMT
Viewed: 
3067 times
  
In lugnet.cad, Don Heyse wrote:
Here's what I'm talking about.  Completely ripped off from the
MLcad.ini file.

  http://ldglite.sf.net/mirror.ini

That one contains an entry every part in my parts.lst file.  It
needs to have the changes made for the exceptions, but here's
how it starts. • [...]
2546.DAT            2546.DAT            0  1 0 0 0 1 0 0 0 1  0 0 0
2546P01.DAT         2546P01.DAT         0  1 0 0 0 1 0 0 0 1  0 0 0
6029A.DAT           6029A.DAT           0  1 0 0 0 1 0 0 0 1  0 0 0

I think I've got a more general solution, but first a quick thought: You could
make mirror.ini more human-readable if the 'normal' parts were just flagged.
Something like:

2546.DAT      default
41770.DAT     exception  41769.DAT     0  1 0 0 0 1 0 0 0 1  0 0 0

On to the weird stuff, apologies if the following covers ground already
discussed.

It seems like mirror.ini will work for the basic case, where parts are not
rotated (or only rotated by 90 degree increments around the Y-axis).  But what
about exception parts at arbitrary orientations?  I'm not very good at thinking
in terms of matrix math, so I worked through a concrete example.

I used the 2x4 wings, 41770 and 41769.  I mirrored along the X axis (my
mistake), but I'll get back to Z axis mirroring in a bit.  The 41770's
X-axis-style entry in MIRROR.INI would be like:
41770.DAT           41769.DAT           0  -1 0 0 0 1 0 0 0 1 0 0 0

So I put a 41770 in a model file and postioned it like this:
1 4 130 -70 -130 .39 -.64 -.66 .6 .72 -.34 .7 -.27 .66 41770.dat

Then I tried to mirror it cleanly.  That is, I wanted to end up with 41769 in
the position/orientation corresponding to my 41770, which means that its final
transformation matrix would be 'non-mirroring'.  What I ended up with is this
LDLite language:
0 TRANSFORM 0 0 0 -1 0 0 0 1 0 0 0 1
  0 TRANSFORM 130 -70 -130 .39 -.64 -.66 .6 .72 -.34 .7 -.27 .66
    1 3 0 0 0 -1 0 0 0 1 0 0 0 1 41769.dat
  0 TRANSFORM END
0 TRANSFORM END

Translated back to simple LDraw, this code turns into:
1 3 -130 -70 -130 .39 .64 .66 -.6 .72 -.34 -.7 -.27 .66 41769.dat

Getting back to mirroring along the Z axis:  I figured out that the correct
equivalent Z axis mirror operation looks like this:
0 TRANSFORM 0 0 0 1 0 0 0 1 0 0 0 -1
  0 TRANSFORM 130 -70 -130 .39 -.64 -.66 .6 .72 -.34 .7 -.27 .66
    1 3 0 0 0 -1 0 0 0 1 0 0 0 1 41769.dat
  0 TRANSFORM END
0 TRANSFORM END

What's interesting is the pre-mirrored part (41769) is inlined with the same transformation as before (-1 0 0 0 1 0 0 0 1).  I expected that I'd have to rotate 41769 180 degrees, and then reposition it, to make things work.

After thinking about it, I think what happened is this:  instead of trying to map 41770 to 41769 in some way that is equivalent to a mirroring operation, I actually replaced the original part with an already-mirrored equivalent statement.  That is, I replaced the '41770.dat' in the first statement with '1 16 0 0 0 -1 0 0 0 1 0 0 0 1 41769.dat', like an inlined subfile.  Since this part was pre-mirrored, applying the mirroring transformation actually 'un-mirrored' the 41769.

So, to make a long story short - I don't think MIRROR.INI should specify how to
transform part A into part B without a mirror operation.  It should specify the
opposite: how to mirror part B into part A with a mirroring operation, so
mirroring-programs can take the transformation being used on part A in the model
file and wrap it around the mirrored part B.

The main practical effect on MIRROR.INI would be that normal parts would have a mirroring transform (1 0 0 0 1 0 0 0 -1) instead of the standard transform.


Steve


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Fri, 18 Jun 2004 23:31:55 GMT
Viewed: 
3200 times
  
In lugnet.cad, Steve Bliss wrote:
In lugnet.cad, Don Heyse wrote:
Here's what I'm talking about.  Completely ripped off from the
MLcad.ini file.

  http://ldglite.sf.net/mirror.ini

That one contains an entry every part in my parts.lst file.  It
needs to have the changes made for the exceptions, but here's
how it starts. [...]
2546.DAT            2546.DAT            0  1 0 0 0 1 0 0 0 1  0 0 0
2546P01.DAT         2546P01.DAT         0  1 0 0 0 1 0 0 0 1  0 0 0
6029A.DAT           6029A.DAT           0  1 0 0 0 1 0 0 0 1  0 0 0

I think I've got a more general solution, but first a quick thought:
You could make mirror.ini more human-readable if the 'normal' parts
were just flagged.  Something like:

2546.DAT      default
41770.DAT     exception  41769.DAT     0  1 0 0 0 1 0 0 0 1  0 0 0

Actually I was thinking of deleting them from the file to make it
smaller.  The only problem is remembering which ones were deleted and
which ones are new at update time.  I'm not sure how to automate
additions either way.  Probably have to use the sorted properties of
parts.lst

So, to make a long story short - I don't think MIRROR.INI should
specify how to transform part A into part B without a mirror operation.
It should specify the opposite: how to mirror part B into part A with
a mirroring operation, so mirroring-programs can take the
transformation being used on part A in the model file and wrap it
around the mirrored part B.

The main practical effect on MIRROR.INI would be that normal parts
would have a mirroring transform (1 0 0 0 1 0 0 0 -1) instead of the
standard transform.

I think that makes sense.  Apply the mirror transform and/or substitution
from MIRROR.INI individually to all parts in the subfile, then apply a
global mirror (across whatever axis you want) to the whole subfile.

It sounds so simple.  Could it be?

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Mon, 21 Jun 2004 13:35:53 GMT
Viewed: 
3234 times
  
In lugnet.cad, Don Heyse wrote:
In lugnet.cad, Steve Bliss wrote:
You could make mirror.ini more human-readable if the 'normal' parts
were just flagged.  Something like:

2546.DAT      default
41770.DAT     exception  41769.DAT     0  1 0 0 0 1 0 0 0 1  0 0 0

Actually I was thinking of deleting them from the file to make it
smaller.  The only problem is remembering which ones were deleted and
which ones are new at update time.  I'm not sure how to automate
additions either way.  Probably have to use the sorted properties of
parts.lst

Keep a full.mirror.ini, with all the default entries.  A simple grep drop the
extra lines, giving us mirror.ini.

I think that makes sense.  Apply the mirror transform and/or substitution
from MIRROR.INI individually to all parts in the subfile, then apply a
global mirror (across whatever axis you want) to the whole subfile.

It sounds so simple.  Could it be?

Well, it depends entirely on whether or not applying two mirroring
transformations always gives an un-mirrored result.  If that's true, then we're
good.

Steve


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Mon, 21 Jun 2004 13:55:35 GMT
Viewed: 
3324 times
  
In lugnet.cad, Steve Bliss wrote:
In lugnet.cad, Don Heyse wrote:
In lugnet.cad, Steve Bliss wrote:
You could make mirror.ini more human-readable if the 'normal' parts
were just flagged.  Something like:

2546.DAT      default
41770.DAT     exception  41769.DAT     0  1 0 0 0 1 0 0 0 1  0 0 0

Actually I was thinking of deleting them from the file to make it
smaller.  The only problem is remembering which ones were deleted and
which ones are new at update time.  I'm not sure how to automate
additions either way.  Probably have to use the sorted properties of
parts.lst

Keep a full.mirror.ini, with all the default entries.  A simple grep
drop the extra lines, giving us mirror.ini.

Or generate a parts.lst (and stash it somewhere) before adding parts,
then diff it with the new parts.lst.  I'm not sure how grep fits into
your plan though...

I think that makes sense.  Apply the mirror transform and/or substitution
from MIRROR.INI individually to all parts in the subfile, then apply a
global mirror (across whatever axis you want) to the whole subfile.

It sounds so simple.  Could it be?

Well, it depends entirely on whether or not applying two mirroring
transformations always gives an un-mirrored result.  If that's true,
then we're good.

My math intuition says it should be.  There are only two choices for
the sign of the determinant, and I think multiplying a negative matrix
by a negative matrix must result in a positive.  Two wrongs *do* make
a right.  Right?

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Mon, 21 Jun 2004 15:00:09 GMT
Viewed: 
3154 times
  
In lugnet.cad, Steve Bliss wrote:
The main practical effect on MIRROR.INI would be that normal parts
would have a mirroring transform (1 0 0 0 1 0 0 0 -1) instead of the
standard transform.

Err, Shouldn't that be (-1 0 0 0 1 0 0 0 1)?  You have to negate the
X coordinate to mirror across the Z axis.

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Mon, 21 Jun 2004 16:12:11 GMT
Viewed: 
3214 times
  
In lugnet.cad, Don Heyse wrote:
In lugnet.cad, Steve Bliss wrote:
The main practical effect on MIRROR.INI would be that normal parts
would have a mirroring transform (1 0 0 0 1 0 0 0 -1) instead of the
standard transform.

Err, Shouldn't that be (-1 0 0 0 1 0 0 0 1)?  You have to negate the
X coordinate to mirror across the Z axis.

Sorry, I misunderstood the terminology.  I figured you could either mirror
across a plane, or along a line.  You can't mirror across a line - it's 1D.  So
I assumed when people were writing about mirroring 'across the Z axis', they
meant to use the XY plane as the mirror.

So, yeah - for right/left mirroring, you'd negate the X coordinate.

Steve


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Mon, 21 Jun 2004 16:32:44 GMT
Viewed: 
3242 times
  
In lugnet.cad, Steve Bliss wrote:
In lugnet.cad, Don Heyse wrote:
In lugnet.cad, Steve Bliss wrote:
The main practical effect on MIRROR.INI would be that normal parts
would have a mirroring transform (1 0 0 0 1 0 0 0 -1) instead of the
standard transform.

Err, Shouldn't that be (-1 0 0 0 1 0 0 0 1)?  You have to negate the
X coordinate to mirror across the Z axis.

Sorry, I misunderstood the terminology.  I figured you could either mirror
across a plane, or along a line.  You can't mirror across a line - it's 1D.
So I assumed when people were writing about mirroring 'across the Z axis',
they meant to use the XY plane as the mirror.

Heh, I was thinking 2-dimensionally.  It's easier for my tired old
brain.  All my sketches were happening on the XZ plane so mirroring
across the Z axis made total sense to me.  Oh well.

So, yeah - for right/left mirroring, you'd negate the X coordinate.

Ok, now I have to follow through and actually make a reference program
which uses the MIRROR.INI file, or this will all be for nothing.

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Mon, 21 Jun 2004 20:02:35 GMT
Viewed: 
2964 times
  
In lugnet.cad, Don Heyse wrote:
It'd be really nice to create a MIRROR.INI file, put it in the ldraw
directory and keep it updated with the parts.  Then if you could put
some wrappers around your program to allow it to be used as an MLCAD
generator and an LDDP plugin, that'd be fantastic.

Is there any documentation about what functionality needs to be exposed to make
an MLCAD plugin?

I've been playing with this in a class-based architecture, that has an
LMirrorExceptionList that contains an array of LMirrorExceptionPart.  I've been
using XmlSerializer to write this to an XML file that looks like:

<?xml version="1.0" encoding="utf-8" ?>
<LMirrorPartList xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
SerialNumber="2004062104">
<ExceptionPartList>
<Part>
<PartFile>3045.dat</PartFile>
<SubstitutePartNumber>3045.dat</SubstitutePartNumber>
<Translation>
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Translation>
<XReflectionMatrix>
<A>1</A>
<B>0</B>
<C>0</C>
<D>0</D>
<E>1</E>
<F>0</F>
<G>0</G>
<H>0</H>
<I>1</I>
</XReflectionMatrix>
<ZReflectionMatrix>
<A>0</A>
<B>0</B>
<C>-1</C>
<D>0</D>
<E>1</E>
<F>0</F>
<G>1</G>
<H>0</H>
<I>0</I>
</ZReflectionMatrix>
<ReverseTransformFor90Rotations>false</ReverseTransformFor90Rotations>
</Part>
<Part>
<PartFile>2357.dat</PartFile>
<SubstitutePartNumber>2357.dat</SubstitutePartNumber>
<Translation>
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Translation>
<XReflectionMatrix>
<A>0</A>
<B>0</B>
<C>1</C>
<D>0</D>
<E>1</E>
<F>0</F>
<G>-1</G>
<H>0</H>
<I>0</I>
</XReflectionMatrix>
<ZReflectionMatrix>
<A>0</A>
<B>0</B>
<C>-1</C>
<D>0</D>
<E>1</E>
<F>0</F>
<G>1</G>
<H>0</H>
<I>0</I>
</ZReflectionMatrix>
<ReverseTransformFor90Rotations>true</ReverseTransformFor90Rotations>
</Part>
</ExceptionPartList>
</LMirrorPartList>.

It's easy enough to add a SaveText() method that would do it as a single-line
text format like your mirror.ini file too, but it's easier to deal with XML than
text parsing!

Ideally, the LMirror program could include an exception list editor.  I can
expose a web service to receive updates to the mirror list and retrieve the most
current list to client apps--that'd be my preferred way to deal with that
problem.

Now that I've played with the problem some more in code, I'm thinking the
approach of defining a rotation + translation to accurately depict the part may
be addressing the symptom, rather than the problem.  Really, the trick is under
what conditions we ignore a part rather than applying a rotation.  Universally
applying a rotation works for the majority of parts for a simple reason: most
parts exhibit symmetry of the X and Z axes about their center of rotation.

If we take, for example, 3747 (slope 33 3 x 2 inverted) being mirrored about the
Z axis (left-to-right mirroring), the 180-degree rotation is desirable for a
part oriented 3 studs across by 2 high but not for one oriented 2 studs across
by 3 high.  (That's what the
<ReverseTransformFor90Rotations>true</ReverseTransformFor90Rotations> element
above was intended to deal with, by applying a 180-degree rotation after the
initial 180-degree rotation for parts oriented under certain conditions--but I
have not thoroughly identified those conditions nor arrived at an optimal
solution yet.)

Please pardon any errors above, and feel free to correct my misunderstandings!
I've only really looked at the LDraw format since last week and am completely
given to errors.

Have you considered making the source code available?

Absolutely.  I'm a little loathe to do so anonymously until I'm at some more
stable code, but if you want it now send me an e-mail and I'll post it when it's
a little more polished.  I've also started a .NET class library to deal with
LDraw data that anyone is welcome to receive.

This brings up a larger question.  LDraw.org is a great resource for anyone
wanting to get started as a user or those dealing with the parts library, but
doesn't contain much information for developers other than the file
specification.  It would be especially instructive to me to see how others have
coped with these rotation/graphics matrix issues, and I can benefit from either
public inspection of my own source or being able to see others' source.  What
resources exist for LDraw developers?  None of the committees really seem
appropriate--the LSC is concerned with the file specification, the Tech List
with the website operations, the Content List with the website contents, and the
parts reviewers for parts issues.

Thanks for humoring my random queries!

Carl


Special: 
[DAT] (requires LDraw-compatible viewer)
Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Tue, 22 Jun 2004 13:40:29 GMT
Viewed: 
3134 times
  
In lugnet.cad, Carl Nelson wrote:
In lugnet.cad, Don Heyse wrote:
It'd be really nice to create a MIRROR.INI file, put it in the ldraw
directory and keep it updated with the parts.  Then if you could put
some wrappers around your program to allow it to be used as an MLCAD
generator and an LDDP plugin, that'd be fantastic.

Is there any documentation about what functionality needs to be
exposed to make an MLCAD plugin?

Hmm, I don't know.  I'm pretty sure there's documentation on language
DLL creation, but I'm not so sure about the generators.  Ask this on the
.mlcad group.

I've been playing with this in a class-based architecture, that has an
LMirrorExceptionList that contains an array of LMirrorExceptionPart.
I've been using XmlSerializer to write this to an XML file

XML works, but it's harder for humans (ie. me) to read.

<PartFile>3045.dat</PartFile>
<SubstitutePartNumber>3045.dat</SubstitutePartNumber>

Under Steve's scheme the exception matrix for 3045.dat would be
created by multiplying a mirror matrix by a rotate 90 matrix.  This
would create a part that looks identical, but is in fact mirrored. So
I don't think you need more than one exception matrix per part.  Look
at this.  The second part looks similar, but is actually mirrored.
That's the exception matrix for MIRROR.INI (except for the -32 Z
offset).

1 2 0 0 0 1 0 0 0 1 0 0 0 1 3045.dat
1 1 0 -32 0 0 0 -1 0 1 0 -1 0 0 3045.dat

Here's Steve's method using homogeneous 4x4 matrices (because they
make the math pretty):

  Default = MD = (-1, 0, 0, 0,   0, 1, 0, 0,    0, 0, 1, 0,    0, 0, 0, 1)
  Exception = ME = (a, d, g, 0,   b, e, h, 0,    c, f, i, 0,    x, y, z, 1)

    For a typical (left right symmetric) part ME = MD

  Current = MC = (A, D, G, 0,   B, E, H, 0,    C, F, I, 0,    X, Y, Z, 1)
  Mirror across an arbitrary plane = MP = (...)
    see http://www.geocities.com/SiliconValley/2151/matrices.html
    (or use a simple mirror across the xy, yz, or xz plane).

  For each part, calculate MF (final matrix) where:
  Mirrored (with no mirrored parts) = MF = MP * MC * ME

It's easy enough to add a SaveText() method that would do it as a
single-line text format like your mirror.ini file too, but it's
easier to deal with XML than text parsing!

Unless the text parsing code is already written.  Then it's the same.
I put the MLCAD.INI (minifig configurator) file parsing in CVS on the
sourceforge, and the proposed MIRROR.INI file uses the same format.
However if you want to convert to and from XML, that's ok with me.

Ideally, the LMirror program could include an exception list editor.
I can expose a web service to receive updates to the mirror list and
retrieve the most current list to client apps--that'd be my
preferred way to deal with that problem.

Sounds like it could work.

Now that I've played with the problem some more in code, I'm
thinking the approach of defining a rotation + translation to
accurately depict the part may be addressing the symptom, rather
than the problem.  Really, the trick is under what conditions we
ignore a part rather than applying a rotation.  Universally applying
a rotation works for the majority of parts for a simple reason: most
parts exhibit symmetry of the X and Z axes about their center of
rotation.

Forget about rotation and use Steve's plan.  Universally applying
2 mirror matrices works for all parts.  In this case, the exceptions
use a default left-right mirror matrix for the initial mirror.

If we take, for example, 3747 (slope 33 3 x 2 inverted)

Under Steve's algorithm, this part is ordinary because of the symmetry
and doesn't need any special considerations, so we could leave it
out of MIRROR.INI.

Please pardon any errors above, and feel free to correct my
misunderstandings!  I've only really looked at the LDraw format
since last week and am completely given to errors.

Have you considered making the source code available?

Absolutely.  I'm a little loathe to do so anonymously until I'm at
some more stable code, but if you want it now send me an e-mail and
I'll post it when it's a little more polished.  I've also started a
.NET class library to deal with LDraw data that anyone is welcome to
receive.

This brings up a larger question.  LDraw.org is a great resource for
anyone wanting to get started as a user or those dealing with the
parts library, but doesn't contain much information for developers
other than the file specification.  It would be especially
instructive to me to see how others have coped with these
rotation/graphics matrix issues, and I can benefit from either
public inspection of my own source or being able to see others'
source.  What resources exist for LDraw developers?

This is the resource.  lugnet.cad.dev.  If you want code, it's
available for many of the programs.  Which ones were you looking for?
Ldglite code is available here.

  http://cvs.sourceforge.net/viewcvs.py/ldglite/ldglite/

I think the L3P parser and matrix functions are fairly easy to follow.
Better than anything I've written, anyways.

You can also look at the old ldraw FAQ.

  http://www.ldraw.org/OLD/community/memorial/archive/FAQ/

It seems to have some info that I can't always find in the newer
divided FAQs and specs.

Enjoy, Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Tue, 22 Jun 2004 20:50:13 GMT
Viewed: 
3323 times
  
In lugnet.cad, Don Heyse wrote:
Under Steve's scheme the exception matrix for 3045.dat would be
created by multiplying a mirror matrix by a rotate 90 matrix.  This
would create a part that looks identical, but is in fact mirrored. So
I don't think you need more than one exception matrix per part.  Look
at this.  The second part looks similar, but is actually mirrored.
That's the exception matrix for MIRROR.INI (except for the -32 Z
offset).

1 2 0 0 0 1 0 0 0 1 0 0 0 1 3045.dat
1 1 0 -32 0 0 0 -1 0 1 0 -1 0 0 3045.dat

Here's Steve's method using homogeneous 4x4 matrices (because they
make the math pretty):

  Default = MD = (-1, 0, 0, 0,   0, 1, 0, 0,    0, 0, 1, 0,    0, 0, 0, 1)
  Exception = ME = (a, d, g, 0,   b, e, h, 0,    c, f, i, 0,    x, y, z, 1)

    For a typical (left right symmetric) part ME = MD

  Current = MC = (A, D, G, 0,   B, E, H, 0,    C, F, I, 0,    X, Y, Z, 1)
  Mirror across an arbitrary plane = MP = (...)
    see http://www.geocities.com/SiliconValley/2151/matrices.html
    (or use a simple mirror across the xy, yz, or xz plane).

  For each part, calculate MF (final matrix) where:
  Mirrored (with no mirrored parts) = MF = MP * MC * ME

Steve, Don--thanks for the explanations; this now makes complete sense to me
(finally!).

For a reflection about the plane containing the Z & Y axes (left-to-right), the
reflection matrix (Mp) should be:

-1 0  0
0  1  0
0  0  1

Then Mp * (part-file rotation matrix from LDraw file) * Mp works for most parts.

Substitute the second Mp for the exception matrix for the exception parts.  The
exception matrix needs to rotate to proper orientation and unmirror the
part--for 2357 (brick 2 x 2 corner), the rotation matrix is:

0  0 -1
0  1  0
1  0  0

To unmirror, the C element should be -1.

Works like a charm so far, and I haven't found any parts that aren't solvable by
a single exception matrix yet.

Anybody see a problem with the algorithm to generate the rotation matrix setting
A = -A and C = -C every time?  One should always be 0, right?

Unless the text parsing code is already written.  Then it's the same.
I put the MLCAD.INI (minifig configurator) file parsing in CVS on the
sourceforge, and the proposed MIRROR.INI file uses the same format.
However if you want to convert to and from XML, that's ok with me.

OK, I haven't done anything else about the config file, but I'll stick with text
if everyone thinks that's a better idea.

Sounds like it could work.

Now I just have to program it! ;-)

Forget about rotation and use Steve's plan.  Universally applying
2 mirror matrices works for all parts.  In this case, the exceptions
use a default left-right mirror matrix for the initial mirror.

Yup.  Far easier!

I better get busy coding...

Thanks,
Carl


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Tue, 22 Jun 2004 21:32:55 GMT
Viewed: 
3468 times
  
In lugnet.cad, Carl Nelson wrote:
In lugnet.cad, Don Heyse wrote:
Under Steve's scheme the exception matrix for 3045.dat would be
created by multiplying a mirror matrix by a rotate 90 matrix.  This
would create a part that looks identical, but is in fact mirrored. So
I don't think you need more than one exception matrix per part.  Look
at this.  The second part looks similar, but is actually mirrored.
That's the exception matrix for MIRROR.INI (except for the -32 Z
offset).

1 2 0 0 0 1 0 0 0 1 0 0 0 1 3045.dat
1 1 0 -32 0 0 0 -1 0 1 0 -1 0 0 3045.dat

Here's Steve's method using homogeneous 4x4 matrices (because they
make the math pretty):

  Default = MD = (-1, 0, 0, 0,   0, 1, 0, 0,    0, 0, 1, 0,    0, 0, 0, 1)
  Exception = ME = (a, d, g, 0,   b, e, h, 0,    c, f, i, 0,    x, y, z, 1)

    For a typical (left right symmetric) part ME = MD

  Current = MC = (A, D, G, 0,   B, E, H, 0,    C, F, I, 0,    X, Y, Z, 1)
  Mirror across an arbitrary plane = MP = (...)
    see http://www.geocities.com/SiliconValley/2151/matrices.html
    (or use a simple mirror across the xy, yz, or xz plane).

  For each part, calculate MF (final matrix) where:
  Mirrored (with no mirrored parts) = MF = MP * MC * ME

Steve, Don--thanks for the explanations; this now makes complete sense
to me (finally!).

For a reflection about the plane containing the Z & Y axes
(left-to-right), the reflection matrix (Mp) should be:

-1 0  0
0  1  0
0  0  1

Then Mp * (part-file rotation matrix from LDraw file) * Mp works for
most parts.

Substitute the second Mp for the exception matrix for the exception
parts.  The exception matrix needs to rotate to proper orientation
and unmirror the part--for 2357 (brick 2 x 2 corner), the rotation
matrix is:

0  0 -1
0  1  0
1  0  0

To unmirror, the C element should be -1.

Err, I'm not sure what you mean by unmirror.  I got
(0 0 1 0 1 0 1 0 0   0 0 0) for a mirror.ini exception matrix, which
looks yours except for the sign of that one number.

Works like a charm so far, and I haven't found any parts that
aren't solvable by a single exception matrix yet.

Me neither.

Anybody see a problem with the algorithm to generate the
rotation matrix setting
A = -A and C = -C every time?  One should always be 0, right?

Unless the text parsing code is already written.  Then it's the same.
I put the MLCAD.INI (minifig configurator) file parsing in CVS on the
sourceforge, and the proposed MIRROR.INI file uses the same format.
However if you want to convert to and from XML, that's ok with me.

OK, I haven't done anything else about the config file, but I'll
stick with text if everyone thinks that's a better idea.

Sounds like it could work.

Now I just have to program it! ;-)
I better get busy coding...

And generating the MIRROR.INI file.  I did some corner parts, some
triangular wings, some minifig arms and legs, and some technic liftarms.
I also created a tiny C program to parse MIRROR.INI and use it to mirror
a file across the ZY plane.  It seems to work so far.  The source, ini,
and a windows command line executable is here:

  http://ldglite.sf.net/mirwin.zip

If anyone wants to update MIRROR.INI for all 2500 parts, that'd be
fantastic.

Enjoy,

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Wed, 23 Jun 2004 02:38:46 GMT
Viewed: 
3655 times
  
In lugnet.cad, Don Heyse wrote:
To unmirror, the C element should be -1.

Err, I'm not sure what you mean by unmirror.  I got
(0 0 1 0 1 0 1 0 0   0 0 0) for a mirror.ini exception matrix, which
looks yours except for the sign of that one number.

Unreflect is a better word--just undo the X coordinate swap that -1 0 0 0 1 0 0 0 1 does.

I believe they're equivalent things--I'm doing a clockwise rotation, then
negating the X coordinate swap, you're doing the opposite rotation.  I think
both work for the part.

Works like a charm so far, and I haven't found any parts that
aren't solvable by a single exception matrix yet.

Me neither.

Yeah, and we don't need no models with no funky new parts that don't mirror
right anyway! ;-)

And generating the MIRROR.INI file.  I did some corner parts, some
triangular wings, some minifig arms and legs, and some technic liftarms.
I also created a tiny C program to parse MIRROR.INI and use it to mirror
a file across the ZY plane.  It seems to work so far.  The source, ini,
and a windows command line executable is here:

  http://ldglite.sf.net/mirwin.zip

If anyone wants to update MIRROR.INI for all 2500 parts, that'd be
fantastic.

Can't promise that--I am adding an exception matrix editor to my program that
should make the task easier though!

Carl


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Wed, 23 Jun 2004 12:53:37 GMT
Viewed: 
3708 times
  
In lugnet.cad, Carl Nelson wrote:
Yeah, and we don't need no models with no funky new parts that don't
mirror right anyway! ;-)

We already got some of them.  The 4360 Space laser gun with side sight
is gonna to be a problem.  You just *know* someone out there'll hook
it up to something by the stud on the asymetric sight portion.  And
there'll be no end to the whining when it mirrors itself right into
some adjacent part.  Oh well.

If anyone wants to update MIRROR.INI for all 2500 parts, that'd be
fantastic.

Can't promise that--I am adding an exception matrix editor to my
program that should make the task easier though!

Don't forget to add a way to keep track of parts that have been
cleared to use the default mirror matrix.  That way we'll know when
the job is done.  (yeah right :^)

Don

PS.  I like your lmirror icon.  How'd you make it?


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Wed, 23 Jun 2004 14:00:37 GMT
Viewed: 
3745 times
  
In lugnet.cad, Don Heyse wrote:
We already got some of them.  The 4360 Space laser gun with side sight
is gonna to be a problem.  You just *know* someone out there'll hook
it up to something by the stud on the asymetric sight portion.  And
there'll be no end to the whining when it mirrors itself right into
some adjacent part.  Oh well.

Yup, oh well.  I guess the mirror specification could always translate it with
no rotation, or add a comment to the LDraw file saying that this part needs to
be checked for proper placement.

PS.  I like your lmirror icon.  How'd you make it?

Thanks!  I put a 2 x 2 red brick by a 1 x 6 x 5 white brick and rendered it with
-lgeo, then Photoshopped it to icon size.

BTW, thanks for the source code!  Makes me realize how rusty my C++ is these
days, since it's been a year or two since I've written anything in it...

Carl


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Wed, 23 Jun 2004 15:12:46 GMT
Viewed: 
3701 times
  
In lugnet.cad, Carl Nelson wrote:
In lugnet.cad, Don Heyse wrote:
To unmirror, the C element should be -1.

Err, I'm not sure what you mean by unmirror.  I got
(0 0 1 0 1 0 1 0 0   0 0 0) for a mirror.ini exception matrix, which
looks yours except for the sign of that one number.

Unreflect is a better word--just undo the X coordinate swap that
-1 0 0 0 1 0 0 0 1 does.

Would that work in general cases, or just for right-left reflection?

I believe they're equivalent things--I'm doing a clockwise rotation, then
negating the X coordinate swap, you're doing the opposite rotation.  I think
both work for the part.

Actually, I think they're not - "Steve's algorithm" (ha!) requires that both the
MP and ME transforms be mirroring, so that the MF transform would be
non-mirroring.

Steve


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Wed, 23 Jun 2004 15:24:46 GMT
Viewed: 
3564 times
  
In lugnet.cad, Don Heyse wrote:
And generating the MIRROR.INI file.  I did some corner parts, some
triangular wings, some minifig arms and legs, and some technic liftarms.
I also created a tiny C program to parse MIRROR.INI and use it to mirror
a file across the ZY plane.  It seems to work so far.  The source, ini,
and a windows command line executable is here:

  http://ldglite.sf.net/mirwin.zip

If anyone wants to update MIRROR.INI for all 2500 parts, that'd be
fantastic.

Dibs on Wings and files starting with 1!

How hard would it be to support normal, self-referential reflections for
patterned parts?  So we could map all 973*.dat parts to themselves, with a
default mirror.

Steve


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Wed, 23 Jun 2004 15:29:13 GMT
Viewed: 
3682 times
  
In lugnet.cad, Steve Bliss wrote:
In lugnet.cad, Carl Nelson wrote:
Unreflect is a better word--just undo the X coordinate swap that
-1 0 0 0 1 0 0 0 1 does.

Would that work in general cases, or just for right-left reflection?

It would need to determine the plane of reflection, and do the second reflection
on the X components for left-right or Z components for front-back.

I believe they're equivalent things--I'm doing a clockwise rotation, then
negating the X coordinate swap, you're doing the opposite rotation.  I think
both work for the part.

Actually, I think they're not - "Steve's algorithm" (ha!) requires that both the
MP and ME transforms be mirroring, so that the MF transform would be
non-mirroring.

I've come up with the same results in all cases so far.  I'll do some thinking
as to which is conceptually easier to generate--ideas?

Carl


Subject: 
Developing MLCAD plugins?
Newsgroups: 
lugnet.cad, lugnet.cad.mlcad
Date: 
Wed, 23 Jun 2004 15:31:07 GMT
Viewed: 
7885 times
  
In lugnet.cad, Don Heyse wrote:
In lugnet.cad, Carl Nelson wrote:
In lugnet.cad, Don Heyse wrote:
It'd be really nice to create a MIRROR.INI file, put it in the ldraw
directory and keep it updated with the parts.  Then if you could put
some wrappers around your program to allow it to be used as an MLCAD
generator and an LDDP plugin, that'd be fantastic.

Is there any documentation about what functionality needs to be
exposed to make an MLCAD plugin?

Hmm, I don't know.  I'm pretty sure there's documentation on language
DLL creation, but I'm not so sure about the generators.  Ask this on the
.mlcad group.

I forwarded this question to here because I don't know the answer.
Apparently there has been some discussion in the past about developing
plugins for MLCAD:

    http://news.lugnet.com/cad/mlcad/?n=177

Is there a specification for plugin development?

Thanks,

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Wed, 23 Jun 2004 15:39:05 GMT
Viewed: 
3560 times
  
In lugnet.cad, Don Heyse wrote:
If anyone wants to update MIRROR.INI for all 2500 parts, that'd be
fantastic.

In mirror.ini, you noted:
; NOTE: I started using the Flags to keep track of which parts I checked.
;          0 = not checked.
;          1 = substitute part
;          2 = mirror across XY plane instead of default of ZY plane
;          3 = mirror and rotate a bit.
;          4 = mirror across XZ plane.  (common for studless technic liftarms)

I'm adding another flag value:
;          5 = checked (ie, reflect across YZ plane)

Some of the flag values should be combinable.  2 and 4 are mutually exclusive,
but 2 and 3 can go together.  So maybe this would be a more rational mapping:
;          0 = not checked.
;          1 = mirror across YZ plane (standard)
;          2 = mirror across XY plane
;          3 = mirror across XZ plane (common for studless technic liftarms)
;          4 = substitute part
;          8 = rotate a bit
Then the 4 and 8 values can be added to the mirror bits.

HTH,
Steve


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Wed, 23 Jun 2004 15:44:47 GMT
Viewed: 
3651 times
  
In lugnet.cad, Steve Bliss wrote:
I'm adding another flag value:
;          5 = checked (ie, reflect across YZ plane)

and another two:
;          6 = asymmetric
;          7 = asymmetric, but in a non-significant way

Part 108 (a shock absorber spring) is getting a 7.

Steve


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Wed, 23 Jun 2004 15:55:29 GMT
Viewed: 
3661 times
  
In lugnet.cad, Steve Bliss wrote:
In lugnet.cad, Don Heyse wrote:
And generating the MIRROR.INI file.  I did some corner parts, some
triangular wings, some minifig arms and legs, and some technic liftarms.
I also created a tiny C program to parse MIRROR.INI and use it to mirror
a file across the ZY plane.  It seems to work so far.  The source, ini,
and a windows command line executable is here:

  http://ldglite.sf.net/mirwin.zip

If anyone wants to update MIRROR.INI for all 2500 parts, that'd be
fantastic.

Dibs on Wings and files starting with 1!

Read the comments at the top of MIRROR.INI in the zip file.  I
already did a bunch of wings.  Only tested one though...
Is there something special about files starting with 1, or
are you taking an alphabetical approach?  Sadly, I created my
sample MIRROR.INI from a PARTS.LST sorted by description, not
part name. :^(

How hard would it be to support normal, self-referential reflections
for patterned parts?  So we could map all 973*.dat parts to themselves,
with a default mirror.

That was my plan, and it takes almost no work.  We just have to mark
them as done somewhere and eventually remove them from MIRROR.INI when
all the parts have been checked.  See the comments in MIRROR.INI to
see how I've been marking the flag field to tag parts I've worked on.
I suppose you could use a flag of 9 to indicate a part that fits the
default profile, so we know we've made a decision on it.  We'll know
we're done when there are no 0 flags left.

Have you tested the mirwiz.exe program on any .LDR files yet?  It's one
way to spot the exceptions not yet handled in MIRROR.INI.  And it's
kinda fun.

Enjoy,

Don


Special: 
[DAT] (requires LDraw-compatible viewer)
Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Wed, 23 Jun 2004 15:58:08 GMT
Viewed: 
3822 times
  
In lugnet.cad, Steve Bliss wrote:
Actually, I think they're not - "Steve's algorithm" (ha!) requires that both the
MP and ME transforms be mirroring, so that the MF transform would be
non-mirroring.

Can you or Don check my work?  I'm trying to figure out why the ME transform
that I did works in my program and the ME that Don put in mirror.ini works in
his code, but not vice-versa.  The most likely explanation is that I'm doing
something stupid.

MP matrix (reflection about the plane containing the Z & Y axes):
-1 0  0
0  1  0
0  0  1

MC matrix (current piece value for a 2357 2 x 2 corner brick)
1 0 0
0 1 0
0 0 1

Don's ME matrix for 2357:
0 0 1
0 1 0
1 0 0

MP * MC =
-1 0  0
0  1  0
0  0  1

(MP * MC) * ME =
0  0 1
0  1 0
-1 0 0

which is a 180-degree rotation out from where it should be.  What's my error
here?

Thanks,
Carl


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Wed, 23 Jun 2004 15:58:23 GMT
Viewed: 
3656 times
  
In lugnet.cad, Don Heyse wrote:
I suppose you could use a flag of 9 to indicate a part that fits the
default profile, so we know we've made a decision on it.  We'll know
we're done when there are no 0 flags left.

Ignore the 9 suggestion, I see you're already way ahead of me on
flag definition.

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Wed, 23 Jun 2004 16:08:24 GMT
Viewed: 
3886 times
  
In lugnet.cad, Carl Nelson wrote:
In lugnet.cad, Steve Bliss wrote:
Actually, I think they're not - "Steve's algorithm" (ha!) requires that both the
MP and ME transforms be mirroring, so that the MF transform would be
non-mirroring.

Can you or Don check my work?  I'm trying to figure out why the ME transform
that I did works in my program and the ME that Don put in mirror.ini works in
his code, but not vice-versa.  The most likely explanation is that I'm doing
something stupid.

Probably.  ;^)


MP matrix (reflection about the plane containing the Z & Y axes):
-1 0  0
0  1  0
0  0  1

MC matrix (current piece value for a 2357 2 x 2 corner brick)
1 0 0
0 1 0
0 0 1

Don's ME matrix for 2357:
0 0 1
0 1 0
1 0 0

MP * MC =
-1 0  0
0  1  0
0  0  1

(MP * MC) * ME =
0  0 1
0  1 0
-1 0 0

which is a 180-degree rotation out from where it should be.  What's my error
here?

Matrix multiplication is not commutative.  (distributive?  Err, I
forget my math terms.)  You're doing one or more of the multiplications
in the wrong order?

Try  ME * (MC * MP) instead.  Notice I switched the order inside the
parens, and outside.

Check how I do it in my code.  You'll probably have to fetch L3Math.c
and L3Def.h from the ldglite CVS archive on the sourceforge to see
the order, because I think I only put the new stuff in the mirwiz.zip
file.

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Wed, 23 Jun 2004 16:36:30 GMT
Viewed: 
3985 times
  
In lugnet.cad, Don Heyse wrote:
Matrix multiplication is not commutative.  (distributive?  Err, I
forget my math terms.)  You're doing one or more of the multiplications
in the wrong order?

It's neither commutative [(a * b) * c != a * (b * c)] nor associative [a * b !=
b * a].

That shouldn't be the problem in the calculation above, since the current matrix
was the identity matrix...

Try  ME * (MC * MP) instead.  Notice I switched the order inside the
parens, and outside.

Check how I do it in my code.  You'll probably have to fetch L3Math.c
and L3Def.h from the ldglite CVS archive on the sourceforge to see
the order, because I think I only put the new stuff in the mirwiz.zip
file.

Looks like you're doing MF = MP * (MC * ME) in the code?

Thanks,
Carl


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad, lugnet.cad.mlcad
Date: 
Wed, 23 Jun 2004 17:52:27 GMT
Viewed: 
8813 times
  
In lugnet.cad, Carl Nelson wrote:
Check how I do it in my code.  You'll probably have to fetch L3Math.c
and L3Def.h from the ldglite CVS archive on the sourceforge to see
the order, because I think I only put the new stuff in the mirwiz.zip
file.

Looks like you're doing MF = MP * (MC * ME) in the code?

Yes, that looks right.

The other thing that messes me up with LDRAW matrices is the row,
column ordering.  The ordering in LDRAW files is not what I would
have chosen, so I always have to look it up.  From the old FAQ:

  http://www.ldraw.org/OLD/community/memorial/archive/FAQ/

Line type 1's format is:

Line Format:
    1 colour x y z a b c d e f g h i part.dat

Fields a through i are orientation & scaling parameters, which can be
used in 'standard' 3D transformation matrices. Fields x, y and z also
fit into this matrix:

    | a d g 0 |
    | b e h 0 |
    | c f i 0 |
    | x y z 1 |

so that every point (x, y ,z) gets transformed to (x', y', z') :

    x' = a*x + b*y + c*z + x
    y' = d*x + e*y + f*z + y
    z' = g*x + h*y + i*z + z

or, in matrix-math style:

                                    | a d g 0 |
    | X' Y' Z' 1 | = | X Y Z 1 | x  | b e h 0 |
                                    | c f i 0 |
                                    | x y z 1 |


Now, I'm not actually sure what the row-column order is in the
MLCAD.INI file.  Since (x,y,z) was moved to last, maybe the 3x3
is laid out in rows instead of columns.  I suppose we should get
that clarified so we use the same format in the MIRROR.INI file.

Here's what MLCAD.INI says:

; <Matrix> a rotation matrix a11 a12 a13 ... a33 for optimal appearance
;          at 0 degree rotation angle
; <Offset> The offset of the part to be in place

I don't know if a12 is b, or if a21 is b. It looks like this in the file:

"Cap"    "4485.DAT"          0  1 0 0 0 1 0 0 0 1  0 0 0

Is that     a b c d e f g h i     x y z   ???

Or is it     a d g b e h c f i     x y z   ???

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad, lugnet.cad.mlcad
Date: 
Wed, 23 Jun 2004 18:00:41 GMT
Viewed: 
8686 times
  
In lugnet.cad, Don Heyse wrote:
The other thing that messes me up with LDRAW matrices is the row,
column ordering.  The ordering in LDRAW files is not what I would
have chosen, so I always have to look it up.  From the old FAQ:

  http://www.ldraw.org/OLD/community/memorial/archive/FAQ/

Line type 1's format is:

Line Format:
    1 colour x y z a b c d e f g h i part.dat

Total side note:  I agree with Don, row/column ordering is not what I would have
chosen.  BUT, it is far easier (IMO) to hand-transform row/column LDraw commands
than the equivalent column/row commands (like I've had to do in POV-Ray code).

Steve


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 24 Jun 2004 14:32:37 GMT
Viewed: 
3879 times
  
What about a flag for default behavior?  I've been coding to ignore ones with default rotations, but there are plenty of parts (especially slopes) that need a (-1 0 0 0 1 0 0 0 1) rotation applied when reflected front-to-back and it would be nice to have a flag to distinguish those needing default behavior from those where the true correction matrix is (-1 0 0 0 1 0 0 0 1).

Carl


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 24 Jun 2004 14:35:56 GMT
Viewed: 
3975 times
  
In lugnet.cad, Carl Nelson wrote:
What about a flag for default behavior?  I've been coding to ignore ones with default rotations, but there are plenty of parts (especially slopes) that need a (-1 0 0 0 1 0 0 0 1) rotation applied when reflected front-to-back and it would be nice to have a flag to distinguish those needing default behavior from those where the true correction matrix is (-1 0 0 0 1 0 0 0 1).

Never mind.  5 would be the correct value for this, right?


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 24 Jun 2004 15:09:39 GMT
Viewed: 
3956 times
  
In lugnet.cad, Carl Nelson wrote:
What about a flag for default behavior?  I've been coding to ignore
ones with default rotations,

Why?  I have a slow PC, and running the mirwiz.exe program is
nearly instantaneous.  It's a lookup and 2 matrix multiplies per
part.  If the exception matrix lookup fails, use the default matrix.
It would take extra, unneeded code to ignore things.  Resist the
urge...

but there are plenty of parts (especially slopes) that need a
(-1 0 0 0 1 0 0 0 1) rotation

Stop saying rotation.  It makes me think you're not doing it right.
That's a mirror matrix.

applied when reflected front-to-back
and it would be nice to have a flag to distinguish those needing
default behavior from those where the true correction matrix is
(-1 0 0 0 1 0 0 0 1).

If you *always* do the same matrix math there's no need to
distinguish.  If you're not, then you're making extra busy work
for yourself and possibly introducing bugs.  Here's the pseudo code.

  for (*ALL* parts in the subfile)
  {
    float m[4][4];  // Tempory working matrix.
    float md[4][4] = { // Default = left-right mirror
      {-1.0,0.0,0.0,0.0},
      {0.0,1.0,0.0,0.0},
      {0.0,0.0,1.0,0.0},
      {0.0,0.0,0.0,1.0}
    };
    float *me = md; // Init exception mirror to left-right (the default).
    float *mp = md; // Init global subfile mirror to left-right.

    for( i=0; i< numExceptions; i++ )
    {
       if (exception[i] matches this part)
       {
  // Use the matrix from the exception list (instead of md).
  me = exception[i].matrix
  // Also use the substitute partname
  strcpy(datname, exception[i].datname);
  break;
}
    }
    M4M4Mul(m,LinePtr->v,me); // Run the initial mirror on the part
    M4M4Mul(LinePtr->v,mp,m); // Apply global subfile mirror to part

    // NOTE: You can set mp to mirror across whatever plane you want.
    //       The example here mirrors the subfile across the YZ plane.
  }

It's simple and it's all done with mirrors, except for a few weird
parts which might contain a rotation and/or translation component
mixed in with the mirroring in the me matrix.

So far I've only found a few door parts that need a translation
component.  See http://ldglite.sf.net/mirror.ini for details on
the doors.

Enjoy,

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 24 Jun 2004 15:18:49 GMT
Viewed: 
4084 times
  
In lugnet.cad, Carl Nelson wrote:
In lugnet.cad, Carl Nelson wrote:
What about a flag for default behavior?  I've been coding to ignore
ones with default rotations, but there are plenty of parts
(especially slopes) that need a (-1 0 0 0 1 0 0 0 1) rotation
applied when reflected front-to-back and it would be nice to have a
flag to distinguish those needing default behavior from those where
the true correction matrix is (-1 0 0 0 1 0 0 0 1).

Never mind.  5 would be the correct value for this, right?

I don't think so.  5 is for keeping track of which parts we've looked
at, not which ones to ignore when your run your mirror program.
Eventually I think we'll remove all the ones marked with a 5 from the
MIRROR.INI file.  (And that includes the left-right symmetric slopes
because they use the default matrix).

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 24 Jun 2004 17:53:31 GMT
Viewed: 
4035 times
  
In lugnet.cad, Don Heyse wrote:
In lugnet.cad, Carl Nelson wrote:
What about a flag for default behavior?  I've been coding to ignore
ones with default rotations,

Why?  I have a slow PC, and running the mirwiz.exe program is
nearly instantaneous.  It's a lookup and 2 matrix multiplies per
part.  If the exception matrix lookup fails, use the default matrix.
It would take extra, unneeded code to ignore things.  Resist the
urge...

Why process something as an exception when the default behavior is needed?  It's
all in what one sees as extra, unneeded code. ;-)

Though I just did some timing and I don't see any performance differences
between ignoring them and not.

but there are plenty of parts (especially slopes) that need a
(-1 0 0 0 1 0 0 0 1) rotation

Stop saying rotation.  It makes me think you're not doing it right.
That's a mirror matrix.

Exception matrix would probably be the best term, since it *always* mirrors and
*may* rotate.

If you *always* do the same matrix math there's no need to
distinguish.  If you're not, then you're making extra busy work
for yourself and possibly introducing bugs.  Here's the pseudo code.

  for (*ALL* parts in the subfile)
  {
    float m[4][4];  // Tempory working matrix.
    float md[4][4] = { // Default = left-right mirror
      {-1.0,0.0,0.0,0.0},
      {0.0,1.0,0.0,0.0},
      {0.0,0.0,1.0,0.0},
      {0.0,0.0,0.0,1.0}
    };
    float *me = md; // Init exception mirror to left-right (the default).
    float *mp = md; // Init global subfile mirror to left-right.

    for( i=0; i< numExceptions; i++ )
    {
       if (exception[i] matches this part)
       {
  // Use the matrix from the exception list (instead of md).
  me = exception[i].matrix
  // Also use the substitute partname
  strcpy(datname, exception[i].datname);
  break;
}
    }
    M4M4Mul(m,LinePtr->v,me); // Run the initial mirror on the part
    M4M4Mul(LinePtr->v,mp,m); // Apply global subfile mirror to part

    // NOTE: You can set mp to mirror across whatever plane you want.
    //       The example here mirrors the subfile across the YZ plane.
  }

It's simple and it's all done with mirrors, except for a few weird
parts which might contain a rotation and/or translation component
mixed in with the mirroring in the me matrix.

My reservation about doing it this way is that it is exclusively tied to a reflection matrix of (-1 0 0 0 1 0 0 0 1)--please see my response to your 2nd message.

So far I've only found a few door parts that need a translation
component.  See http://ldglite.sf.net/mirror.ini for details on
the doors.

Same here.  BTW, do you want me to send you the parts that I've changed
mirror.ini for already?  I've also confirmed some as correct by rotating
different models.

Carl


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 24 Jun 2004 17:54:55 GMT
Viewed: 
4163 times
  
In lugnet.cad, Don Heyse wrote:
I don't think so.  5 is for keeping track of which parts we've looked
at, not which ones to ignore when your run your mirror program.
Eventually I think we'll remove all the ones marked with a 5 from the
MIRROR.INI file.  (And that includes the left-right symmetric slopes
because they use the default matrix).

IMO there *is* value to knowing that the proper exception matrix is indeed an
exception rather than coincidentally the same as the default matrix.  If the 5
is not the place for this, there should be a new flag for it.

It's especially important if all the 5s are removed.  If so, the left-right symmetric slopes with an exception matrix of -1 0 0 0 1 0 0 0 1 will only function properly for left-right reflections because that's the only case where their exception matrix would equal the "default" matrix.  ("Default" in quotes because it should probably be the mirror-plane matrix or some other term that describes what it is.)

Of course, this supports your methodology of treating every part listed in
mirror.ini as an exception regardless of whether it happens to use the
reflection matrix. ;-)  But it would still fail if those true exceptions were
removed.

Thanks,
Carl


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 24 Jun 2004 18:57:26 GMT
Viewed: 
4186 times
  
In lugnet.cad, Carl Nelson wrote:
In lugnet.cad, Don Heyse wrote:
I don't think so.  5 is for keeping track of which parts we've looked
at, not which ones to ignore when your run your mirror program.
Eventually I think we'll remove all the ones marked with a 5 from the
MIRROR.INI file.  (And that includes the left-right symmetric slopes
because they use the default matrix).

IMO there *is* value to knowing that the proper exception matrix is
indeed an exception rather than coincidentally the same as the
default matrix.  If the 5 is not the place for this, there should be
a new flag for it.

Sure, but you still haven't convinced me there's any difference
between a 2x2 brick and a 2x2 slope brick.  I must be getting senile
in my old age, because I just don't get it.

Anyhow, use 55 if it makes you happy.  We'll figure out what to do
with it later when my brain starts working.  Steve's already switched
over to some other weird notation for the flag field.  Maybe you
should send him a note and you two can duke it out.  And perhaps you
can send my your code and it'll all become clear to me.  I don't know.

It's especially important if all the 5s are removed.  If so, the
left-right symmetric slopes with an exception matrix of -1 0 0 0 1 0
0 0 1 will only function properly for left-right reflections because
that's the only case where their exception matrix would equal the
"default" matrix.  ("Default" in quotes because it should probably be
the mirror-plane matrix or some other term that describes what it
is.)

What do you mean by function properly?  As far as I know, I can
change the global subfile mirror matrix (mp in my code sample) to a
mirror across *any* arbitrary plane and it should still work.  I've
compiled mirwiz.c with a front-back mp and it still works.

    float mm[4][4] = { // Front-back mirror
      {1.0,0.0,0.0,0.0},
      {0.0,1.0,0.0,0.0},
      {0.0,0.0,-1.0,0.0},
      {0.0,0.0,0.0,1.0}
    };
    //float *mp = md; // Init global mirror to left-right.
    float *mp = mm; // Init global mirror to front-back.

What else do you need to function properly?  The whole point of the
exception matrix is to prepare each part so that the *real* mirror
(the global subfile mirror operation) is in fact an UNmirror operation
because all the parts are already mirrored.  You just can't tell
they're already mirrored unless you look at the backwards logos in
MLCAD or POV output.

Go ahead and try it.  Just apply the exception matrices to a
subfile.  It should come out looking identical.  But if you look
really close at the logos in MLCAD you'll see they're backwards,
ready to be fixed by *any* mirror operation.  (Don't use ldview
or ldglite though because they fix the logos on the fly if they
detect a negative determinant.)

Am I mistaken about this somehow?  Does it somehow produce parts
that aren't mirrored, but also aren't real?  Show me the mangled
LDR file.

Of course, this supports your methodology of treating every part
listed in mirror.ini as an exception regardless of whether it happens
to use the reflection matrix. ;-) But it would still fail if those
true exceptions were removed.

I'm still not seeing that.  Steve?  Help me out here.  What am I
missing?

BTW, do you want me to send you the parts that I've changed
mirror.ini for already?  I've also confirmed some as correct by
rotating different models.

You're not a SourceForge member, are you?  This merging would be so
much simpler if we could just let CVS merge the changes for us.
Since you're probably not, maybe you could send the changes to Steve.
(and send me a copy too)  He's taking a rational approach.  Doing
the ones and then the two's, whereas I just fool around and look
at wings or doors or whatever strikes my fancy.

Have fun,

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad, lugnet.cad.mlcad
Date: 
Thu, 24 Jun 2004 20:33:22 GMT
Viewed: 
8758 times
  
Hi Don,

now it's getting interesting ...

"Don Heyse" <dheyse@hotmail.spam.go.away.com> schrieb im Newsbeitrag
news:HzrwBF.9t2@lugnet.com...
<SNIP>
Line type 1's format is:

Line Format:
    1 colour x y z a b c d e f g h i part.dat

Fields a through i are orientation & scaling parameters, which can be
used in 'standard' 3D transformation matrices. Fields x, y and z also
fit into this matrix:

    | a d g 0 |
    | b e h 0 |
    | c f i 0 |
    | x y z 1 |

I'm actually reading it in as
| a b c |
| d e f |
| g h i |

and that is also how I'm writing my matrixes of meta commands ....
if that is wrong, why do I not have any problem when reading files?!?!?!? -
I'm a bit confused now ...

<SNIP>
Here's what MLCAD.INI says:

Please read also the specification of MLCad extensions in the developer
section of my web-pages. It explains nearly everything. - except the read
order shown above.

Regards,
   Michael


Subject: 
Re: Developing MLCAD plugins?
Newsgroups: 
lugnet.cad, lugnet.cad.mlcad
Date: 
Thu, 24 Jun 2004 20:35:21 GMT
Viewed: 
8050 times
  
Done,

"Don Heyse" <dheyse@hotmail.spam.go.away.com> schrieb im Newsbeitrag
news:Hzrprv.14sB@lugnet.com...
<SNIP>

Is there a specification for plugin development?


No sorry, MLCad does not support plugins yet, currently I have a very quick
way introducing new generators and pseudo commands by hand - but I'll check
if I could do some more automation here to be able to load such things as
plugins.

Thanks,

Don

Regards,
   Michael


Subject: 
Re: Developing MLCAD plugins?
Newsgroups: 
lugnet.cad, lugnet.cad.mlcad
Date: 
Thu, 24 Jun 2004 21:01:56 GMT
Viewed: 
8143 times
  
In lugnet.cad, Michael Lachmann wrote:
Is there a specification for plugin development?

No sorry, MLCad does not support plugins yet, currently I have a very quick
way introducing new generators and pseudo commands by hand - but I'll check
if I could do some more automation here to be able to load such things as
plugins.

While you're checking, think about this.  What if the MLCad generators
were reconfigured as some sort of plugins, and the plugin specs were
documented?  Then everyone could use your generators.  You know, weird
people like me who are frightened off by too many toolbars, or those
crazy people who insist on editing their LDRAW code in a text editor
like LDDP. ;^)

Enjoy,

Don


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 24 Jun 2004 21:06:32 GMT
Viewed: 
4069 times
  
In lugnet.cad, Carl Nelson wrote:
Why process something as an exception when the default behavior is needed?
It's all in what one sees as extra, unneeded code. ;-)

Well, yeah.  But it's simpler to process it all -- the only exceptional
processing you need is "look for the part in mirror.ini.  If not found, use the
default settings".

With your method, you have to also add "if the matrix looks like MD, then
process with method_a; otherwise, use method_b".

HOWEVER, you should process all parts through the mirroring operation -
otherwise, you can't handle parts at arbitrary orientations.  And if you apply
just the reflection matrix (MP), you'll get reversed stud-logos in your
renderings.

Exception matrix would probably be the best term, since it *always* mirrors > and *may* rotate.

Or transformation matrix, or pre-reflection matrix.

Steve


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 24 Jun 2004 21:11:29 GMT
Viewed: 
4161 times
  
Oops, I missed replying to one point.

In lugnet.cad, Carl Nelson wrote:
My reservation about doing it this way is that it is exclusively tied to a
reflection matrix of (-1 0 0 0 1 0 0 0 1)--please see my response to your
2nd message.

If you mean (-1 0 0 0 1 0 0 0 1) as the 'default' matrix, my response is: that default matrix works for *any* reflection across any arbitrary plane.

If you mean (-1 0 0 0 1 0 0 0 1) as the reflection matrix, my response is: Don's algorithm works for *any* reflection across any arbitrary plane.

Steve


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 24 Jun 2004 21:23:03 GMT
Viewed: 
4257 times
  
In lugnet.cad, Steve Bliss wrote:
Oops, I missed replying to one point.

In lugnet.cad, Carl Nelson wrote:
My reservation about doing it this way is that it is exclusively tied to a
reflection matrix of (-1 0 0 0 1 0 0 0 1)--please see my response to your
2nd message.

If you mean (-1 0 0 0 1 0 0 0 1) as the 'default' matrix, my response is:
that default matrix works for *any* reflection across any arbitrary plane.

If you mean (-1 0 0 0 1 0 0 0 1) as the reflection matrix, my response is:
Don's algorithm works for *any* reflection across any arbitrary plane.

Uh, I thought we were refering to it as "Steve's algorithm".  Are you
having 2nd thoughts?  ;^)

Enjoy,

Don

PS.  Why am I constantly seeing really long lines in the browser for this
thread.  It makes things really hard to read when I have to scroll 2
miles to the right.


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Thu, 24 Jun 2004 21:49:15 GMT
Viewed: 
4284 times
  
In lugnet.cad, Don Heyse wrote:
Uh, I thought we were refering to it as "Steve's algorithm".  Are you
having 2nd thoughts?  ;^)

Sorry, I should have said "Don's pseudo-code". ;)

PS.  Why am I constantly seeing really long lines in the browser for this
thread.  It makes things really hard to read when I have to scroll 2
miles to the right.

I don't know - I'm replying via the web interface, posting with plain text.


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Fri, 25 Jun 2004 02:43:13 GMT
Viewed: 
4309 times
  
In lugnet.cad, Steve Bliss wrote:
Oops, I missed replying to one point.

In lugnet.cad, Carl Nelson wrote:
My reservation about doing it this way is that it is exclusively tied to a
reflection matrix of (-1 0 0 0 1 0 0 0 1)--please see my response to your
2nd message.

If you mean (-1 0 0 0 1 0 0 0 1) as the 'default' matrix, my response is: that default matrix works for *any* reflection across any arbitrary plane.

If you mean (-1 0 0 0 1 0 0 0 1) as the reflection matrix, my response is: Don's algorithm works for *any* reflection across any arbitrary plane.

Alright, I give up then.  I've accomplished my original goal of mirroring a
model, and I'm just confusing and frustrating myself and wasting your and Don's
time with stupid questions.

I've put the newest executable & source code at:

http://www.carlnelson.com/page.asp?SID=1&Page=43

Thanks,
Carl


Subject: 
Re: Quick way to mirror-image a model?
Newsgroups: 
lugnet.cad
Date: 
Fri, 2 Jul 2004 21:08:06 GMT
Viewed: 
4618 times
  
In lugnet.cad, Carl Nelson wrote:
I've put the newest executable & source code at:

http://www.carlnelson.com/page.asp?SID=1&Page=43

Before I forget, Steve finished examining all the parts, so
I've put the complete mirror.ini file here for now.

  http://ldglite.sourceforge.net/mirwiz.zip

Enjoy,

Don


Subject: 
Re: Developing MLCAD plugins?
Newsgroups: 
lugnet.cad, lugnet.cad.mlcad
Date: 
Sun, 4 Jul 2004 06:35:55 GMT
Viewed: 
8493 times
  
Don,

"Don Heyse" <dheyse@hotmail.spam.go.away.com> schrieb im Newsbeitrag
news:Hztzr8.y0t@lugnet.com...
<SNIP>
While you're checking, think about this.  What if the MLCad generators
were reconfigured as some sort of plugins, and the plugin specs were
documented?  Then everyone could use your generators.  You know, weird
people like me who are frightened off by too many toolbars, or those
crazy people who insist on editing their LDRAW code in a text editor
like LDDP. ;^)

Enjoy,

Don

That will be documented anyway - sure. But for that feature I have to think
even more ...
but I have already an idea how that could work.
I just need to find a spare hour where I can hack a quick prototype, to see
the cons and pros of this
idea.

Best regards,
   Michael


©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR