EasyDeformer (Script)

Aus CINEMA 4D Wiki

Wechseln zu: Navigation, Suche
Der Inhalt dieses Artikels ist noch in in Bearbeitung.

Bitte entschuldigen Sie unvollständigen Text und bearbeiten Sie diesen Artikel nicht selbst, da zur Zeit Cineast noch daran schreibt.

Inhaltsverzeichnis

Ziel / Idee des Skripts

Das Script soll den Arbeitsfluss mit Deformern beschleunigen. Normalerweise muss ein Deformer dem zu deformierenden Objekt untergeordnet, sowie Position, Rotation und Größe des Deformers an das Objekt angepasst werden. Ziel des Scripts war es eine '1-Click-Lösung' zu implementieren, die dann zb. auch für schnellen Zugriff in das Cinema Layout eingefügt werden kann.

Funktion

Das Skript kann nur aktiviert werden wenn ein Objekt in der Szene ausgewählt ist (das zu deformierende Objekt). Wenn das Skript aufgerufen wurde erscheint ein Dialog in dem der geünschte Deformer ausgewählt werden kann. Nach Bestätigen des Dialogs wird der Deformer als Kind des momentan aktiven Objekts eingefügt, und an dessen Größe,Position und Drehung angepasst.

Einschränkungen

Zur Zeit werden nur folgende Deformer unterstützt: Bend,Shear,Taper,Twist und Bulge. Evtl. wird das Skript bei Gelegenheit erweitert um auch noch die restlichen Deformer zu unterstützen.

Erläuterungen zum Code

TODO..


Code

      //---------------------------------------
      // EasyDeformer
      //
      // Inserts basic Deformers at position of selected object.
      // Also inherits rotation and scale, by computing bounding box.
      // Works for poly-Objects and all primitives except Figure.
      // If used on poly-Objects, objects should have their axis centered before,
      // else deformer dimensions may be off.
      //
      // by BellaLugosi
      //---------------------------------------
      
      
      // returns bounding box size vector of given object
      GetBoundingBox(obj){
      	var count = obj->GetPointCount();
      	var points = (obj->GetPoints());
      	var maxPoint = vector(0,0,0);
      	var i;
      	for (i = 0; i < count; i++)	{
      		var x = abs(int(points[i].x + 0.5)); if(x > maxPoint.x) maxPoint.x = x;
      		var y = abs(int(points[i].y + 0.5)); if(y > maxPoint.y) maxPoint.y = y;
      		var z = abs(int(points[i].z + 0.5)); if(z > maxPoint.z) maxPoint.z = z;	
      	}	
        return maxPoint*2; // dist from center times two equals size
      }
      
      // type of deformer to put around the active object
      var deformerType;
      
      //The dialog
      class InstanceDialog : GeModalDialog {
      	public:
      		CreateLayout();
      		Command(id,msg);
      };
      
      InstanceDialog::CreateLayout() {
      	SetTitle("EasyDeformer");
      	
      	AddGroupBeginH(0,BFH_SCALEFIT,3,"",0);
      		AddStaticText(0,BFH_SCALEFIT,0,0,"Select Deformer to use:",0);
      		AddComboBox(1000,BFH_SCALEFIT, 80, 12);
      		AddItem(1000, obend, "Bend");
      		AddItem(1000, otwist, "Twist");
      		AddItem(1000, obulge, "Bulge");
      		AddItem(1000, oshear, "Shear");
      		AddItem(1000, otaper, "Taper");
      
      		AddDlgGroup(DR_DLGGROUP_OK|DR_DLGGROUP_CANCEL);
      	AddGroupEnd();
      }
      
      InstanceDialog::Command(id,msg) {
      	deformerType=GetInt(1000);
      	// use default deformer
      	if(deformerType==0) deformerType=obend;
      }
      
      main(doc,op)
      {
      
      	// Get the active object
      	var op = doc->GetActiveObject();
      	if(!op) return;
      
      	// open Dialog
      	var dlg=new(InstanceDialog);
      //dlg->SetDimensions();
      	dlg->Open(NOTOK,NOTOK);
      	if (!dlg->GetResult()) return FALSE;  
      
      	var size = vector(0,0,0);
      	var type = op->GetType();
      
      	// is it a poly object ?
      	if(op->IsInstanceOf(opolygon)) 
      		size =  GetBoundingBox(op);
      	else if(type>5153 && type<5174) // or a primitive ?	
      	{
      		// create polyobject from input object
      		var bc = new(BaseContainer);
      		SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT,   doc, op, bc, MODIFY_ALL);
      		//doc->Message(MSG_UPDATE);
      		var clone = doc->GetActiveObject();
      		clone->SetName("copy");
      	
      		//compute bounding box
      		size = GetBoundingBox(clone);
      		// remove poly object
      		clone->Remove();
      	} 
      	else return; // else incompatible object (like spline or array or sth)
      
      	// compute some deformer offset from the average size of the objects sides
      	var _offset = int((size.x+size.y+size.z) / 100 + 0.5);
      	// apply offset
      	size+=_offset; 
      
      	// insert deformer object as child of selected object
      	var deformer = AllocObject(deformerType);
      	// align deformer to parent obbject
      	var zeroVec = vector(0,0,0);
      	deformer->SetPosition(zeroVec);
      	deformer->SetRotation(zeroVec);
      	// resize deformer
      	var deformer_bc = deformer->GetContainer();
      	deformer_bc->SetData(DEFORMOBJECT_SIZE,size);
      	deformer->SetContainer(deformer_bc);
      
      	// add deformer as child of selected object
      	deformer->InsertUnder(op);
      	// add undo
      	doc->AddUndo(UNDO_OBJECT_NEW,deformer);
      	// De-select all objects
      	CallCommand(12113);
      	// select Deformer
      	op->GetDown()->SetBit(BIT_AOBJ);
      	// Update document
      	doc->Message(MSG_UPDATE);
      }
Persönliche Werkzeuge