PointLocatorData

Object Hierarchy | 関連する C++クラス:PointLocatorData

導入

v5.0

詳細

PointLocatorData オブジェクトは、ポイントロケータのコレクションを示します。ポイントロケータはジオメトリックサーフェイス座標で、ジオメトリ上の正確な位置を示します。ポイントロケータは、位相的に定義されるため、位置またはジオメトリのデフォーメーションに依存しません(サーフェイスに固定されます)。ポイントロケータの実際のデータは、抽出されジオメトリタイプに依存します。

ポイント ロケータは Point を一般化したものです。ポイントとして、ポイント ロケータはジオメトリ タイプとは別個に処理できます。ポイントインデックスのように、ポイントロケータは特定のジオメトリインスタンスには関連していません。同じPointLocatorDataと同じトポロジを持つジオメトリを問い合わせることができます。インスタンスのために、ポイントロケータを使用して異なる時間にアニメーションのジオメトリの位置を検証することができます。

ポイントロケータは特定のジオメトリインスタンスに適用できないため、PointLocatorData オブジェクトにはそれ自体の機能がありません。PointLocatorData に関連するほとんどのメソッドは、GeometryPolygonMesh、および NurbsSurfaceMesh で定義されます。PointLocatorData は、Geometry.GetClosestLocationsGeometry.GetClosestLocationsWithinRadiusGeometry.GetRaycastIntersectionsGeometry.GetSurfacePointLocatorsFromPointsNurbsSurfaceMesh.ConstructPointLocators、および PolygonMesh.ConstructPointLocators メソッドを使用して作成できます。

PointLocatorData の使用方法のその他の例は、PointLocatorData.CountPolygonMesh.ConstructPointLocators など、関連するさまざまなメソッドに記載されています。

ポイントロケータは現在、PolygonMesh および NurbsSurfaceMesh オブジェクトのみでサポートされています。

プロパティ

Countオペレータ      
       

1. Python の例

#

#	This example uses PointLocatorData to shrink-wrap a sphere to a cube,

#	and then pushes the sphere along cube's normals.

#

app = Application

app.NewScene( "", 0 )

root = app.ActiveSceneRoot

CubeGeom = root.AddGeometry("Cube", "MeshSurface").ActivePrimitive2.Geometry

SphereObj = root.AddGeometry("Sphere", "MeshSurface")

SphereObj.subdivv = 24

SphereObj.subdivu = 24

# Freeze it, otherwise its position array cannot be set:

app.FreezeObj(SphereObj)

SphereGeom = SphereObj.ActivePrimitive2.Geometry

SphereOnCubePointLocators = CubeGeom.GetClosestLocations(SphereGeom.Points.PositionArray)

SphereOnCubePositions = CubeGeom.EvaluatePositions(SphereOnCubePointLocators)

SphereOnCubeNormals = CubeGeom.EvaluateNormals(SphereOnCubePointLocators)

SphereNewPositions = []

i = 0

while i < len(SphereOnCubePositions) :

	j = 0

	tmplist = []

	while j < len(SphereOnCubePositions[i]) :

		tmplist.append( SphereOnCubeNormals[i][j]*3 )

		j = j + 1

	SphereNewPositions.append(tmplist)

	i = i + 1

SphereGeom.Points.PositionArray = SphereNewPositions;

2. JScript の例

/*

	This example uses PointLocatorData to deform a polygon mesh based on

	the closest weight map value of a NURBS surface mesh.

*/

// Scene creation:

//     Polygon mesh grid and a NURBS surface grid.

//     On the NURBS grid, a weight map having a radial gradient

NewScene( null, false );

var root = Application.ActiveSceneRoot;

var MeshGridObj = root.AddGeometry("Grid", "MeshSurface");

MeshGridObj.subdivu = 24;

MeshGridObj.subdivv = 24;

// We must freeze it, otherwise setting its position array will be forbidden:

FreezeObj(MeshGridObj);

var MeshGridGeom = MeshGridObj.ActivePrimitive.Geometry;

var NURBSGridObj = root.AddGeometry("Grid", "NurbsSurface");

NURBSGridObj.subdivu = 2;

NURBSGridObj.subdivv = 2;

var NURBSGridGeom = NURBSGridObj.ActivePrimitive.Geometry;

var NURBSWeightMap = CreateWeightMap(null, NURBSGridObj, "Weight_Map").item(0);

SetValue(NURBSWeightMap + ".weightmapop.type", 5);

SetValue(NURBSWeightMap + ".weightmapop.weight", 1);

SetValue(NURBSWeightMap + ".weightmapop.invert", true);

NURBSWeightMap = GetValue(NURBSWeightMap);	// Get the weight map again to have an updated copy

// Applying the deformation

var MeshGridPos = MeshGridGeom.Points.PositionArray.toArray();

var MeshGridOnNURBSGridPointLocators = NURBSGridGeom.GetClosestLocations(MeshGridPos);

var WeightMapValuesForMesh = NURBSGridGeom.EvaluateClusterProperty(	MeshGridOnNURBSGridPointLocators,

									NURBSWeightMap.Parent,

									NURBSWeightMap ).toArray();

// Push mesh vertices along Y, modulated by NURBS grid's closest surface's weight map value

for(i = 0; i < MeshGridPos.length; i+=3)

	MeshGridPos[i+1] += WeightMapValuesForMesh[i/3]*5;

MeshGridGeom.Points.PositionArray = MeshGridPos;

3. JScript の例

// The following example is more complex but shows the PointLocatorData 

// at work in the context of a relatively complex scripted operator.

//

// This example creates a "skinning" custom operator, which a kind

// of shrink wrap-based cage deform operator. This operator

// wraps a deformed "body" object with a "skin" object having a different

// topology. In order to create the surface correspondance between

// the skin and the body, it uses a static copy of the "body", which

// is not animated and stands as a reference. The operator supports,

// too, arbitrary poses on each object.

//

// Since the skin and the reference body are not animated, the

// custom operator can create the point locators only once,

// at the first evaluation, and then only need to evaluate

// them on the deformed body at each frame. This improves a lot

// the performance since creating point locators from spatial

// proximity is much more costly than simply evaluating their

// positions or normals.

//

// Additionally, in order to improve the skinning result, the

// operator pushes the sking along the normals of the body,

// and the amplitude of this push can be controlled by a parameter.

NewScene( null, false );

var root = Application.ActiveSceneRoot;

Translate("Camera", 0, 0, 50.0, siRelative, siView, siObj, siXYZ);

// Create the reference body object, non-animated object (a cube),

// and move it to a non-trivial pose

var ReferenceCubeObj = root.AddGeometry("Cube", "MeshSurface");

Translate(ReferenceCubeObj, -25.0, 0, 0, siRelative, siView, siObj, siXYZ);

// Create the skin object (a sphere with more resolution),

// and move it to a non-trivial pose

var ShrinkWrappedSphereObj = root.AddGeometry("Sphere", "MeshSurface");

ShrinkWrappedSphereObj.subdivu = 25;

ShrinkWrappedSphereObj.subdivv = 25;

Rotate(ShrinkWrappedSphereObj, 0, 0, -60.0, siRelative, siLocal, siObj, siXYZ);

Scale(ShrinkWrappedSphereObj, 1.5, 1.5, 1.5, siRelative, siLocal, siObj, siXYZ);

Translate(ShrinkWrappedSphereObj, -25.0, 0, 0, siRelative, siView, siObj, siXYZ);

// Create the animated target body object.

// In order to show the scripted op at work, add kinematic and

// shape animation.

var TargetCubeObj = root.AddGeometry("Cube", "MeshSurface");

Translate(TargetCubeObj, 10.0, 10.0, 0, siRelative, siView, siObj, siXYZ);

SetValue("Context.constructionmode", 1);

Scale("cube1.pnt[2,3,6,LAST]", 0.3, 0.3, 0.3, siRelative, siLocal, siObj, siXYZ);

SaveShapeKey("cube1.pnt[2,3,6,LAST]", null, null, 1);

Scale("cube1.pnt[2,3,6,LAST]", 10.0, 10.0, 10.0, siRelative, siLocal, siObj, siXYZ);

SaveShapeKey("cube1.polymsh.cls.Shape", null, null, 100);

SaveKey("cube1.kine.local.posx,cube1.kine.local.posy,cube1.kine.local.posz");

SaveKey("cube1.kine.local.rotx,cube1.kine.local.roty,cube1.kine.local.rotz");

Rotate(TargetCubeObj, 50.0, 0, 50.0, siRelative, siLocal, siObj, siXYZ);

SetValue("PlayControl.Current", 100);

SaveKey("cube1.kine.local.rotx,cube1.kine.local.roty,cube1.kine.local.rotz", 100);

Translate(TargetCubeObj, -15.0, -15.0, 0.0, siRelative, siView, siObj, siXYZ);

SaveKey("cube1.kine.local.posx,cube1.kine.local.posy,cube1.kine.local.posz", 100);

SetValue("PlayControl.Current", 1);

// Apply the scripted op to the skin.

var SkinOp = ApplySkinOp( ShrinkWrappedSphereObj, ReferenceCubeObj, TargetCubeObj );

SetValue("PlayControl.Loop", true);

PlayForwardsFromStart();

InspectObj(SkinOp);

function ApplySkinOp( inSkinObj, inReferenceBody, inTargetBody )

{

	var op = XSIFactory.CreateScriptedOp( "MySkinOp", MySkinOp_Update.toString(), "JScript" );

	// Define connections

	var skin_group = op.AddPortGroup( "SkinGroup" );

	op.AddIOPort( inSkinObj.ActivePrimitive, "Geom", skin_group.Index );

	op.AddInputPort( inSkinObj.Kinematics.Global, "Pose", skin_group.Index );

	var ref_group = op.AddPortGroup( "ReferenceBodyGroup" );

	op.AddInputPort( inReferenceBody.ActivePrimitive, "Geom", ref_group.Index );

	op.AddInputPort( inReferenceBody.Kinematics.Global, "Pose", ref_group.Index );

	var tgt_group = op.AddPortGroup( "TargetBodyGroup" );

	op.AddInputPort( inTargetBody.ActivePrimitive, "Geom", tgt_group.Index );

	op.AddInputPort( inTargetBody.Kinematics.Global, "Pose", tgt_group.Index );

	// Define a parameter for the push amplitude

	var pdef = XSIFactory.CreateParamDef2( "PushAmplitude", siDouble, 2, -1, 5 );

	op.AddParameter(pdef);

	// Connect operator

	op.Connect(inSkinObj + ";" + inReferenceBody + ";" + inTargetBody);

	return op;

}

// This function contains the implementation of the scripted operator.

function MySkinOp_Update( ctx, out, InSkinGeom, InSkinPose, InReferenceBodyGeom, InReferenceBodyPose, InTargetBodyGeom, InTargetBodyPose )

{

	// TransformPositionArray: transforms in place an array of packed XYZ vectors

	function TransformPositionArray( array, transfo )

	{

		for (i = 0; i < array.length; i+=3)

		{

			var TempVector3 = XSIMath.CreateVector3()

			TempVector3.Set(array[i], array[i+1], array[i+2]);

			TempVector3.MulByTransformationInPlace(transfo);

			var XYZArray = TempVector3.Get2().toArray();

			array[i] = XYZArray[0];

			array[i+1] = XYZArray[1];

			array[i+2] = XYZArray[2];

		}

	}

	var SkinGeom = InSkinGeom.Value.Geometry;

	var ReferenceBodyGeom = InReferenceBodyGeom.Value.Geometry;

	/////////////////////////////////////////////////////////

	//1) Create skin point locators relatively to the surface 

	//   proximity to the reference body. We intentionally keep

	//   a snapshot of the point locators to speed up the 

	//   next evaluations; we assume that InSkinGeom, InSkinPose, 

	//   InReferenceBodyGeom and InReferenceBodyPose are not

	//   animated.

	var SkinPointLocators = ctx.UserData;

	if(SkinPointLocators == null)	// No user data means that this is the first evaluation of the operator

	{

		// The skin object and the reference may have different poses, so we

		// will compute the surface proximity computation in global space.

		// We will use the closest smoothed surface method (2==siClosestSmoothedSurface).

		ReferenceBodyGeom.SetupPointLocatorQueries(2, InReferenceBodyPose.Value.Transform); 

		// Transform the skin positions in global space

		var SkinGeomPosArray = SkinGeom.Points.PositionArray.toArray();

		// TransformPositionArray: transforms in place an array of packed XYZ vectors

		TransformPositionArray( SkinGeomPosArray, InSkinPose.Value.Transform );

		SkinPointLocators = ReferenceBodyGeom.GetClosestLocations(SkinGeomPosArray);

		ctx.UserData = SkinPointLocators;

	}

	/////////////////////////////////////////////////////////

	//2) Evaluate the point locators on the target body, and

	//   displace them along target body's normals, with the

	//   amplitude given by the scirted op parameter.

	var TargetBodyGeom = InTargetBodyGeom.Value.Geometry;

	var SkinOnTargetBodyPositions = TargetBodyGeom.EvaluatePositions(SkinPointLocators).toArray();

	var SkinOnTargetBodyNormals = TargetBodyGeom.EvaluateNormals(SkinPointLocators).toArray();

	var SkinToTargetTransform = XSIMath.MapWorldPoseToObjectSpace(InSkinPose.Value.Transform, InTargetBodyPose.Value.Transform);

	var dPushAmplitude = ctx.Parameters("PushAmplitude").Value

	for (i = 0; i < SkinOnTargetBodyPositions.length; i++)

		SkinOnTargetBodyPositions[i] += SkinOnTargetBodyNormals[i]*dPushAmplitude;

	// TransformPositionArray: transforms in place an array of packed XYZ vectors

	TransformPositionArray( SkinOnTargetBodyPositions, SkinToTargetTransform );

	SkinGeom.Points.PositionArray = SkinOnTargetBodyPositions;

}

関連項目

Geometry Geometry.GetClosestLocations Geometry.GetClosestLocationsWithinRadius Geometry.GetRaycastIntersections Geometry.SetupPointLocatorQueries Geometry.GetSurfacePointLocatorsFromPoints Geometry.EvaluatePositions Geometry.EvaluateNormals Geometry.EvaluateClusterProperty PolygonMesh.GetPolygonIndexArray PolygonMesh.GetTriangleVertexIndexArray PolygonMesh.GetTriangleNodeIndexArray PolygonMesh.GetTriangleWeightArray PolygonMesh.ConstructPointLocators NurbsSurfaceMesh.GetSubSurfaceIndexArray NurbsSurfaceMesh.GetNormalizedUVArray NurbsSurfaceMesh.ConstructPointLocators