Anim8or Community

Please login or register.

Login with username, password and session length
Advanced search  

News:

An update to Anim8or, v1.00b, is available with a few bug fixes. Get your copy HERE. See the "ReadMe" file for details.

Author Topic: EXPERIMENTAL Mirroring Script  (Read 4363 times)

CobraSpectre

  • Newbie
  • *
  • Posts: 39
    • View Profile
EXPERIMENTAL Mirroring Script
« on: September 24, 2008, 10:37:09 pm »

First, I have to thank Kubajzz for finding this 'feature' in anim8or. The code below is obviously built on his code.

Second, this is still highly experimental, it causes my CPU to go to 100% utilization which may cause problems and random restarts due to heat. Use at your own risk.

Notes:
  • This attempts to create real time mirroring for modeling. A new mesh is created that is mirrored around the X axis. Point edits, and object rotation carry over to the mirrored mesh. Materials work depending on situation, texture coordinates have not been tested.
  • Adding the open and close to the mesh at each cycle prevents RAM use from going out of control while removing the condition to update. RAM and page file may still go up, please monitor them from the Task Manager.
  • It appears to be possible to catch the mesh mid-update and it may not draw correctly. Interface workaround: if you are using the one display or four display pressing "1" or "4" respectively will force anim8or to redraw.
  • Either mesh can be moved without affecting the other. The mirrored mesh can be added to a group without a problem and can be independently rotated.
  • The script looks for a mesh named "mesh01" to mirror.
  • The script exits when there is an attribute named "STOP".
  • Exiting anim8or without stopping the script causes anim8or to quit with an error.
  • When switching to other modes CPU stays at full, CPU drops when a menu is opened.
  • Running this script prevents other scripts from running.

There's still more that can be done to improve the script. I'm hoping Anim8or can improve to make this easier to work with.

Update:
Correct Normals
Code: [Select]
#command("object");

/* X axis mesh mirror, USE AT YOUR OWN RISK */

shape $S, $NewS;
attribute $Attr;
int $i, $j;
point3 $pointedit;
quaternion $rotedit;

$S = project.curObject.LookupShape("mesh01"); /*get the original shape */

if ($S != NULL) {

$Attr = project.curObject.LookupAttribute("STOP");

/* create a copy */
$NewS = mesh();


while ($Attr == NULL) {

  $NewS.Open();

  /* copy the points and faces */
  for $i = 0 to $NewS.GetNumPoints()-1 do {
    $NewS.SetPointSelected($i, true);
  }
  $NewS.DeleteSelectedPoints();

  /* correct orientaton */
  $rotedit = $S.orientation;
  $rotedit.y = -$rotedit.y;
  $rotedit.z = -$rotedit.z;
  $NewS.orientation = $rotedit;

  for $i = 0 to $S.GetNumPoints()-1 do {
    $pointedit = $S.GetPoint($i);
    $pointedit.x = -$pointedit.x; /* mirror around X axis, invert x values*/
    $NewS.AddPoint($pointedit);
  }

  for $i = 0 to $S.GetNumFaces()-1 do {
    $NewS.OpenFace(0, 0);
    for $j = 0 to $S.GetNumSides($i)-1 do {
      $NewS.VertexN($S.GetFacePointIndex($i, $S.GetNumSides($i)-1-$j));
    }
    $NewS.CloseFace();
  }

    $NewS.Close();

  /* check for attribute to stop the cycle */
  $Attr = project.curObject.LookupAttribute("STOP");
}

}
« Last Edit: September 25, 2008, 06:27:01 am by CobraSpectre »
Logged

CowTail

  • Jr. Member
  • **
  • Posts: 72
    • View Profile
Re: EXPERIMENTAL Mirroring Script
« Reply #1 on: September 24, 2008, 11:04:43 pm »

Err, have you really even tried this script out? It doesn't mirror exactly across the Y-axis from the original mesh, the normals are flipped, and on line 48:
Code: [Select]
NewS.CloseFace();

Needs to be:
Code: [Select]
$NewS.CloseFace();

Or else there'll be errors.

Well, that's for me anyway, with 0.97d. I do hope you get this working well enough! Perhaps turn it into a button in the toolbar where you select the mesh instead, then press the button to activate the mirroring on that mesh? Also, support for subdivision meshes would be outstanding (and as I mentioned before, group the mirrored portion so that it's locked and can't be manipulated by the user)
Logged

CobraSpectre

  • Newbie
  • *
  • Posts: 39
    • View Profile
Re: EXPERIMENTAL Mirroring Script
« Reply #2 on: September 24, 2008, 11:12:37 pm »

Oops, fixed now.
Logged

neirao

  • Sr. Member
  • ****
  • Posts: 570
  • Neirao
    • View Profile
Re: EXPERIMENTAL Mirroring Script
« Reply #3 on: September 25, 2008, 09:37:13 pm »

if has possible set "Division Work" by asl script,

be good for make "MIRROR SUBDIVIDED OBJECTS"... ,

- the script converter object to -- >
1 - division work = 0;
2 -converter to mesh --> and --> mirror object;
3 - converter to Subidivided object and back to "division work"  previos...

i make this question in: http://www.anim8or.com/smf/index.php?topic=1158.0

but...its no is possible.... :'(
« Last Edit: September 25, 2008, 09:40:37 pm by neirao »
Logged

CobraSpectre

  • Newbie
  • *
  • Posts: 39
    • View Profile
Updated Mirroring Script
« Reply #4 on: September 29, 2008, 05:12:56 am »

New version info:

Instead of using the mesh's name, select the mesh to mirror before running the script.

You can choose to mirror the X, Y, or Z axis. It defaults to X automatically. For Y and Z, create a string attribute named "Mirror" with a value of "Y" or "Z".

Code: [Select]
#command("object");

/* X, Y, Z axis mesh mirror, USE AT YOUR OWN RISK */

shape $S, $NewS, $AS[0], $AS2[0];
attribute $Attr, $AxisAttr;
int $i, $j;
point3 $pointedit;
quaternion $rotation;
string $AxisStr;

project.curObject.GetShapes($AS);

for $i = $AS.size-1 to 0 step -1 do {
  if ($AS[$i].Selected == 1)
    $AS2.push($AS.pop());
  else
    $AS.pop();
}

if ($AS2.size == 1)
  $S = $AS2[0];

if ($S.Selected == 1) {

$Attr = project.curObject.LookupAttribute("STOP");

/* create a copy */
$NewS = mesh();


while ($Attr == NULL) {

  $NewS.Open();

  /* copy the points and faces */
  for $i = 0 to $NewS.GetNumPoints()-1 do {
    $NewS.SetPointSelected($i, true);
  }
  $NewS.DeleteSelectedPoints();

  $AxisAttr = project.curObject.LookupAttribute("Mirror");
  $AxisStr = $AxisAttr.GetStringValue();

  if ($AxisStr != "Y" && $AxisStr != "Z") { /* X axis mirror is default behavior */
    /* correct orientaton for X*/
    $rotation = $S.orientation;
    $rotation.y = -$rotation.y;
    $rotation.z = -$rotation.z;
    $NewS.orientation = $rotation;

    for $i = 0 to $S.GetNumPoints()-1 do {
      $pointedit = $S.GetPoint($i);
      $pointedit.x = -$pointedit.x; /* mirror around X axis */
      $NewS.AddPoint($pointedit);
    }
  }

  if ($AxisStr == "Y") {
    /* correct orientaton for Y*/
    $rotation = $S.orientation;
    $rotation.x = -$rotation.x;
    $rotation.z = -$rotation.z;
    $NewS.orientation = $rotation;

    for $i = 0 to $S.GetNumPoints()-1 do {
      $pointedit = $S.GetPoint($i);
      $pointedit.y = -$pointedit.y; /* mirror around Y axis */
      $NewS.AddPoint($pointedit);
    }
  }

  if ($AxisStr == "Z") {
    /* correct orientaton for Z*/
    $rotation = $S.orientation;
    $rotation.x = -$rotation.x;
    $rotation.y = -$rotation.y;
    $NewS.orientation = $rotation;

    for $i = 0 to $S.GetNumPoints()-1 do {
      $pointedit = $S.GetPoint($i);
      $pointedit.z = -$pointedit.z; /* mirror around Z axis */
      $NewS.AddPoint($pointedit);
    }
  }

  for $i = 0 to $S.GetNumFaces()-1 do {
    $NewS.OpenFace(0, 0);
    for $j = 0 to $S.GetNumSides($i)-1 do {
      $NewS.VertexN($S.GetFacePointIndex($i, $S.GetNumSides($i)-1-$j));
    }
    $NewS.CloseFace();
  }

    $NewS.Close();

  /* check for attribute to stop the cycle */
  $Attr = project.curObject.LookupAttribute("STOP");
}
}
Logged

Kubajzz

  • Flying Platypus
  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 548
  • Little doggie ate my avatar...
    • View Profile
Re: EXPERIMENTAL Mirroring Script
« Reply #5 on: October 01, 2008, 06:07:59 am »

Great job CobraSpectre!

Nice to see crazy ideas coming true ;)
Logged

RavenWorks

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: EXPERIMENTAL Mirroring Script
« Reply #6 on: October 11, 2008, 02:37:47 pm »

Interesting! This is the one feature that Anim8or is truly missing, for me...

It looks like the script causes so much slowdown because it's running constantly, right?
Would it be possible (and more stable) to make a button that updates the duplicate whenever you click it?
Logged