I'm working on a script (JScript) that create some extrusions from a polygon to get this kind of result:
In this scene, i started from a sphere and perform a 5-stage extrusion with an angle of 90° and a distance of 10. The first object (tagged "1" on the picture) is the center of "rotation". The second object (tagged "2") is used to get the relative plan from the selected quad
The problem is to get a realtime visualisation, in other term, create the extrusions, and destroy it to re-create all with new parameters. I have a PPG inspector with these parameters, and the user is able to select the value he want. To get a realtime visualisation, i need to undo all the previous operations. I've tried:
- Undoing all the extrusions with a loop of "Undo (null);". It doesn't work because when the user modify a value in the PPG, it's undoed too.
- Growing selection and delete all the extrusions: i can't find a way to cap the hole without having to pick a vertex or the edges and cap it manually.
- Saving the operations in an array to delete them and get the initial polymesh: i can't access a global variable in the PPG callback (when changing a value in the inspector of the script). It's seem to be a pure JScript problem because of how the PPG system work. And the DuplicateMeshComponent function (used to get an extrusion on the current polygon) doesn't seem to return
a reference to the corresponding operation on the XSI explorer, so i can't do a "DeleteObj(MyOperation);".
Here is the code. you can create a new scene with a sphere, select a polygon and run the script, and just hitting "OK" to get the same result i have posted before. It doesn't work on some angles but it's another problem. If you try to change the distance value, the extrusions will be added again and again, giving a funny result but not really what we want
Code: Select all
onGUI();
function onGUI()
{
if(!isAlreadyOpened()){
var oPSet = CreatePSet() ;
var oLayout = oPSet.PPGLayout;
oLayout.Logic =OnInit.toString()+
CreateLayout.toString()+
onValide_OnClicked+
PivotDistance_OnChanged.toString()+
PivotAngle_OnChanged.toString()+
HingeAngle_OnChanged.toString()+
HingeStage_OnChanged.toString()+
AngleCornet_OnChanged.toString()
;
//Close_OnClicked.toString();
oLayout.Language = "JScript" ;
}
else
{
DeleteObj("Hingeissler");
var oPSet = CreatePSet() ;
var oLayout = oPSet.PPGLayout;
oLayout.Logic =OnInit.toString()+
CreateLayout.toString()+
onValide_OnClicked+
PivotDistance_OnChanged.toString()+
PivotAngle_OnChanged.toString()+
HingeAngle_OnChanged.toString()+
HingeStage_OnChanged.toString()+
AngleCornet_OnChanged.toString()
//Close_OnClicked.toString();
oLayout.Language = "JScript" ;
}
//p.UserData =new Array('a', 'b', 'mpilgrim', 'z', 'example');
var CurrentPolygon=Selection.Item(0);
SetTransientReferencePlane(CurrentPolygon);
oPSet.NullName.Value=GetPrim("Null", null, null, null);
Rotate(null, 0, 0, 0, siAbsolute, siObjCtr, siObj, siX, null, null, null, null, null, null, null, 0, null);
Rotate(null, 0, 0, 0, siAbsolute, siObjCtr, siObj, siY, null, null, null, null, null, null, null, 0, null);
Rotate(null, 0, 0, 0, siAbsolute, siObjCtr, siObj, siZ, null, null, null, null, null, null, null, 0, null);
Translate(null, 0, 0, 0, siAbsolute, siObjCtr, siObj, siX, null, null, null, null, null, null, null, null, null, 0, null);
Translate(null, 0, 0, 0, siAbsolute, siObjCtr, siObj, siY, null, null, null, null, null, null, null, null, null, 0, null);
Translate(null, 0, 0, 0, siAbsolute, siObjCtr, siObj, siZ, null, null, null, null, null, null, null, null, null, 0, null);
oPSet.PivotName.Value=GetPrim("Null", null, null, null);
MatchTransform(oPSet.PivotName.Value, oPSet.NullName.Value, siSRT, null);
Translate(oPSet.PivotName.Value, Math.cos(oPSet.PivotAngle.Value*Math.PI/180.0)*oPSet.PivotDistance.Value, 0, Math.sin(oPSet.PivotAngle.Value*Math.PI/180.0)*oPSet.PivotDistance.Value, siAbsolute, siObjCtr, siObj, siXYZ, null, null, null, null, null, null, null, null, null, 0, null);
oPSet.Polygone.Value=CurrentPolygon;
InspectObj( "Hingeissler", null, null, null, false );
}
function OnInit()
{
// Create the initial layout
CreateLayout();
}
function isAlreadyOpened(){
var properties = ActiveSceneRoot.Properties;
for(var i=0;i<properties.Count;i++){
if(properties(i)=="Hingeissler")return true;
}
return false;
}
function CreatePSet()
{
var oPSet = ActiveSceneRoot.AddProperty( "CustomProperty", false, "Hingeissler" ) ;
var tab=new Array();
oPSet.AddParameter3( "PivotDistance", siInt2,"10" ) ;
oPSet.AddParameter3( "PivotAngle", siInt2,"90" ) ;
oPSet.AddParameter3( "HingeAngle", siFloat,"90" ) ;
oPSet.AddParameter3( "HingeStage", siInt2,"5" ) ;
oPSet.AddParameter3( "AngleCornet", siFloat,"1" ) ;
oPSet.AddParameter3( "NullName", siString,"" ) ;
oPSet.AddParameter3( "PivotName", siString,"" ) ;
oPSet.AddParameter3( "Polygone", siString,"" ) ;
oPSet.AddParameter3( "Numberop", siString,"" ) ;
return oPSet ;
}
function CreateLayout()
{
var oLayout = PPG.PPGLayout ;
oLayout.Clear() ; // Flush old layout
oLayout.AddRow();
oLayout.AddItem( "PivotDistance", "Pivot Distance");
oLayout.EndRow() ;
oLayout.AddRow();
oLayout.AddItem( "PivotAngle", "Pivot Angle");
oLayout.EndRow() ;
oLayout.AddRow();
oLayout.AddItem( "HingeAngle", "Hinge Angle");
oLayout.EndRow() ;
oLayout.AddRow();
oLayout.AddItem( "HingeStage", "Hinge Stage");
oLayout.EndRow() ;
oLayout.AddRow();
oLayout.AddItem( "AngleCornet", "Cornet Angle");
oLayout.EndRow() ;
oLayout.AddRow();
oLayout.AddButton( "onValide", "OK" ) ;
oLayout.EndRow() ;
PPG.Refresh();
}
function onValide_OnClicked()
{
SetSelFilter("Polygon");
SelectGeometryComponents(PPG.Polygone.Value);
for (i=1; i<=PPG.HingeStage.Value; i++)
{
DuplicateMeshComponent(PPG.Polygone.Value, siPersistentOperation, null, null, null, null, null, null, null, null, null, null, null, null, null);
SetTransientReferencePlane(PPG.PivotName.Value);
Rotate(null,PPG.HingeAngle.Value/PPG.HingeStage.Value, 0, 0, siRelative, siObjCtr, siObj, siXYZ, null, null, null,null,null,null,null, 0, null);
}
}
function PivotDistance_OnChanged()
{
/*
for (i=0; i<PPG.HingeStage.Value; i++)
{
Undo(null);
Undo(null);
Undo(null);
}*/
Translate(PPG.PivotName.Value, Math.cos(PPG.PivotAngle.Value*Math.PI/180.0)*PPG.PivotDistance.Value, 0, Math.sin(PPG.PivotAngle.Value*Math.PI/180.0)*PPG.PivotDistance.Value, siAbsolute, siObjCtr, siObj, siXYZ, null, null, null, null, null, null, null, null, null, 0, null);
SetSelFilter("Polygon");
SelectGeometryComponents(PPG.Polygone.Value);
for (i=1; i<=PPG.HingeStage.Value; i++)
{
DuplicateMeshComponent(PPG.Polygone.Value, siPersistentOperation, null, null, null, null, null, null, null, null, null, null, null, null, null);
SetTransientReferencePlane(PPG.PivotName.Value);
Rotate(null,PPG.HingeAngle.Value/PPG.HingeStage.Value, 0, 0, siRelative, siObjCtr, siObj, siXYZ, null, null, null,null,null,null,null, 0, null);
}
}
function PivotAngle_OnChanged()
{
Translate(PPG.PivotName.Value, Math.cos(PPG.PivotAngle.Value*Math.PI/180.0)*PPG.PivotDistance.Value, 0, Math.sin(PPG.PivotAngle.Value*Math.PI/180.0)*PPG.PivotDistance.Value, siAbsolute, siObjCtr, siObj, siXYZ, null, null, null, null, null, null, null, null, null, 0, null);
}
function HingeAngle_OnChanged()
{
for (i=0; i<PPG.HingeStage.Value; i++)
{
Undo(null);
Undo(null);
Undo(null);
}
SetSelFilter("Polygon");
SelectGeometryComponents(PPG.Polygone.Value);
for (i=1; i<=PPG.HingeStage.Value; i++)
{
DuplicateMeshComponent(PPG.Polygone.Value, siPersistentOperation, null, null, null, null, null, null, null, null, null, null, null, null, null);
SetTransientReferencePlane(PPG.PivotName.Value);
Rotate(null,PPG.HingeAngle.Value/PPG.HingeStage.Value, 0, 0, siRelative, siObjCtr, siObj, siXYZ, null, null, null,null,null,null,null, 0, null);
}
}
function HingeStage_OnChanged()
{
}
function AngleCornet_OnChanged()
{
}
Thanks for your help. I believe this script could be very useful, for CAO optimisation and modelisation of non-biological objects.