Functions

rigidAlignment(...) Finds transformation matrix 4x4 that transforms geomFloating to geomFixed based on a set of user specified point correspondences.
nonRigidRegistration(...) Wraps geomFloating around geomFixed and returns a wrapped copy of geomFloating.
transferTexture(...) Transfer texture from geomSrc to geomDst using ray-tracing.
subdivide(geom,nSubdivisions = 1) Subdivide geometry using Catmull-Clark subdivision
projectMesh(...) Project geomSrc onto geomDst using ray-tracing.
decimate(...) Decimate geometry down to targetPolygonCount polygons.
repairGeom(geom) Convert non-manifold topology to manifold.
savePoints(points, fileName) Save list of wrap.PointOnTriangle to text file.
loadPoints(fileName) Load list of wrap.PointOnTriangle from text file.
savePolygons(polygons, fileName) Save list of polygon indices to text file.
loadPolygons(fileName) Load list of polygon indices from text file.
subset(geom, polygonIndices) Returns new geometry which contains specified polygons from geom.
applySubset(geom, geomSubset, vertexMapping) Replace some vertex coordinates from geom by vertex coordinates from geomSubset according to vertexMapping
transferPolygroups(geomFrom, geomTo) Transfer polygroups from geomFrom onto geomTo
latticeDeform(geomTarget, geomSource, ...) Deforms geomTarget based on how you reshape control geometry (geomSource and geomReference).
computeBlendShape(neutralGeom, targetGeoms, ...) Compute blendshape with specific weights.
extractMarvelousAvatar(avatarFileName) Extract Marvelous Designer avatar (.AVT) into wrap.Geom.
embedMarvelousAvatar(geom, ...) Embed intance of wrap.Geom into Marvelous Designer avatar (.AVT) file.
isActivated() Check if WrapX activated
activate(licenseKey) Activate WrapX
wrap.rigidAlignment(geomFloating, pointsFloating, geomFixed, pointsFixed, matchScale = True)

Finds transformation matrix 4x4 that transforms geomFloating to geomFixed based on a set of user specified point correspondences. pointsFloating and pointsFixed should be the same length.

Parameters:

geomFloating : wrap.Geom

Geometry to be transformed

pointsFloating : sequence of wrap.PointOnTriangle

A set of points on geomFloating

geomFixed : wrap.Geom

Geometry to match to

pointsFixed : sequence of wrap.PointOnTriangle

A set of points on geomFixed

matchScale : bool, optional

If False the resulting matrix will only rotate and translate the floating geometry. If True it will also match the scale of floating model to fixed model. Defaults to True

Returns:

result : wrap.Matrix4x4

Returns matrix 4x4 that will transform geomFloating to geomFixed

Examples

# finding transformation matrix
m = wrap.rigidAlignment(geomFloating,pointsFloating,geomFixed,pointsFixed)
# applying the transformation
geomFloating.transform(m)
wrap.nonRigidRegistration(geomFloating, geomFixed, controlPointsFloating = [], controlPointsFixed = [], freePolygonIndicesFloating = [], initialRadiusMultiplier = 1.0, radiusMultiplier = 4.0, minNodes = 10, smoothnessInitial = 1.0, smoothnessFinal = 0.1, multiplierControlPoints = 10.0, maxIterations = 30, mu = 1e-12, subdivisionPercentage = 1.0, scaleMultiplier = 2.0)

Wraps geomFloating around geomFixed and returns a wrapped copy of geomFloating.

Parameters:

geomFloating : wrap.Geom

Basemesh geometry to be wrapped around geomFixed. Should have manifold topology, use wrap.meshRepair to convert non-manifold topology to manifold.

Basemesh should be reasonably small (several thousands of polygons would work fine).

Meshes with hundreds of thousands of polygons would require too much time and RAM to compute.

It is highly recommended for the basemesh to contain a single piece of connected geometry. If the basemesh contains small separated parts like eyeballs or eyelashes that might lead to bad results.

The algorithm performs wrapping in several steps called levels. On each level the algorithm sub-samles vertices of basemesh to create control nodes. It warps the shape of the basemesh by changing nodes’ positions. It tries to find such position of control nodes so that basemesh match the scan. When the best possible match is found with the given number of nodes the algorithm goes to next level. It sub-samples the nodes again with smaller radius and continue wrapping with more control nodes. The more nodes the slower the computations and the more accurate the result. The final density of control nodes is controlled by initialRadiusMultiplier. radiusMultiplier controls how fast the nodes’ density will grow with each iteration.

geomFixed : wrap.Geom

Scan or other high-poly model. For better performance geomFixed should not exceed 10M polygons. If this is the case it is recommended to decimate the mesh using geomFloating = wrap.decimate(geomFloating, nPolygons)

controlPointsFloating, controlPointsFixed : sequence of wrap.PointOnTriangle, optional

A set of correspondent points on geomFloating and geomFixed. In many cases the algorithm can work without control points at all. Use control points to help the algorithm to find proper solution. controlPointsFloating and controlPointsFixed should be the same length.

freePolygonIndicesFloating : sequence of int, optional

A set of polygon indices on geomFloating that will be treated as Free polygons. Free polygons only tend to stay as rigid as possible and do not tend to stitch to target surface. That is very useful in some cases:

  • when there are some areas on scan (like back side of ears) that contain too many artifacts and noise, so it is better to leave correspondent piece of basemesh unchanged.
  • when actor has a hat or stocking on his head and wrapping basemesh’s part around the hat would make no sense, it’s better to leave it unchanged.

The polygon indices should be in range [0,geomFloating.nPolygons]

initialRadiusMultiplier : float, optional

Controls the final density of control nodes. Defaults to 1.0 which is equal to median nearest point distance across basemesh. The lower the value the more nodes will control the basemesh at last iterations, the better the quality of wrapping, the smaller details can be captured by basemesh. On the other hand it will increase the time of the computation and RAM usage.

radiusMultiplier : float, optional

Controls how fast the number of control nodes will grow with each iteration. Defaults to 4.0.

minNodes : int, optional

Defines the minimal number of control nodes at the beginning of optimization. Defaults to 10. Increase it in case of creating morph-targets and if the shape differences between basemesh and a scan are big.

smoothnessInitial : float, optional

Defines the initial rigidness of the basemesh on first iterations. The more rigid the basemesh the harder for the algorithm to deform it. Increase the value if the target mesh contains much noise and outliers. Defaults to 1.0.

smoothnessFinal : float, optional

Defines the rigidness of the basemesh on final iterations. The less the rigidness the easier for the algorithm to deform the mesh, the better it reflects the shape of the target mesh. Defaults to 0.1. Increase the value if you do not want the basemesh to capture small details of the scan.

multiplierControlPoints : float, optional

Controls the influence of control points. Defaults to 10.0.

maxIterations : int, optional

Number of iterations of the algorithm. The less the value the faster the algorithm and the less accurate the result. Defaults to 30.

mu : double, optional

Controls the precision of the algorithm. Defaults to 1e-12.

subdivisionPercentage : double, optional

Defines what percentage of control nodes should be re-sampled on each level. Defaults to 1.0. For most cases leave unchanged.

Returns:

result : wrap.Geom

Returns wrapped copy of geomFloating

wrap.transferTexture(geomSrc, textureSrc, geomDst, textureSizeDst, maxRelativeDist = 3.0)

Transfer texture from geomSrc to geomDst using ray-tracing. If ray from geomSrc does not hit any polygons on geomDst it will produce transparent pixel on resulting texture.

Parameters:

geomSrc : wrap.Geom

Geometry to project from

textureSrc : wrap.Image

Texture to project

geomDst : wrap.Geom

Geometry to project to

maxRelativeDist : number, optional

Limits the maximum distance of projection, defaults to 3.0. Actual maximum distance is maxRelativeDist * medianNearestPointDistanceDst, where medianNearestPointDistanceDst is a median distance from each point to nearest neighbour point on geomDst.

Returns:

result : wrap.Image

Returns the texture for geomDst

wrap.subdivide(geom, nSubdivisions = 1)

Subdivide geometry using Catmull-Clark subdivision

Parameters:

geom : wrap.Geom

Input geometry, should have a manifold topology

nSubdivisions : int, optional

Number of subdivisions, defaults to 1. subdivide(geom,2) is equivalent to subdivide(subdivide(geom))

Returns:

result : wrap.Geom

Returns subdivided geometry. Returned geometry will have the same visual properties and a texture as geom

wrap.projectMesh(geomSrc, geomDst, maxRelativeDist = 1.0, disabledPolygonIndicesSrc = [], checkNormalsCompatibility = True)

Project geomSrc onto geomDst using ray-tracing.

Parameters:

geomSrc, geomDst : wrap.Geom

Geometry to project from and to

maxRelativeDist : number, optional

Limits the maximum distance of projection, defaults to 1.0

It is useful to reduce the value if there are some artifacts occur during projection on such areas like mouth, eyes, ears etc. The actual maximum distance is computed as maxRelativeDist * medianNearestPointDist, where medianNearestPointDist is median distance from mesh point to nearest neighbour point.

disabledPolygonIndicesSrc : list of int, optional

The list of indices of polygons on geomSrc that should not be modified during projection.

checkNormalsCompatibility : bool, optional

If True the vertex only projects on a polygon that has normal direction similar to the vertex’s one. That leads to less artifacts on thin surfaces. Defaults to True.

Returns:

result : wrap.Geom

Return new geometry that is the copy of geomSrc with vertex positions projected onto geomDst.

wrap.decimate(geomSource, targetPolygonCount, preserveTexCoords = True)

Decimate geometry down to targetPolygonCount polygons.

Parameters:

geom : wrap.Geom

Geometry to decimate

targetPolygonCount : int

Desired number of polygons. It should be not greater that geom.nPolygons. To decimate to specific percentage use:

targetPolygonCount = geom.nPolygons * percentage

preserveTexCoords : bool, optional

If True the returned model will preserve UV-coordinates so that you can apply the same texture that was applied to geom. However that will prevent some edges of the mesh from collapsing that might lead to produce more irregular mesh. Defaults to True.

Returns:

result : wrap.Geom

Returns new geometry with number of polygons >= targetPolygonCount.

wrap.repairGeom(geom)

Convert non-manifold topology to manifold.

Parameters:

geom : wrap.Geom

Non-manifold geometry

Returns:

result : wrap.Geom

Manifold geometry

wrap.savePoints(points, fileName)

Save list of wrap.PointOnTriangle to text file.

List of points is usually produced by wrap.selectPoints().

Parameters:

points : list

fileName : string

Name of the file to save.

wrap.loadPoints(fileName)

Load list of wrap.PointOnTriangle from text file.

Parameters:

fileName : string

Name of the file previously created by wrap.savePoints().

Returns:

result : list of wrap.PointOnTriangle

wrap.savePolygons(polygons, fileName)

Save list of polygon indices to text file.

List of polygons is usually produced by wrap.selectPolygons().

Parameters:

polygons : list

List of polygon indices.

fileName : string

Name of the file to save.

wrap.loadPolygons(fileName)

Load list of polygon indices from text file.

Parameters:

fileName : string

Name of the file previously created by wrap.savePolygons().

Returns:

result : list of int

List of polygon indices.

wrap.subset(geom, polygonIndices)

Returns new geometry which contains specified polygons from geom.

Usage:
geomSubset, vertexMapping = subset(geom, polygonIndices)
Parameters:

geom : wrap.Geom

Input geometry.

polygonIndices : sequence of int

list of polygon indices from input geometry.

Returns:

result : (geomSubset, vertexMapping)

geomSubset : wrap.Geom

geometry which contains polygons from geom according to polygonIndices.

vertexMapping : list of int

mapping from new vertex positions (from geomSubset) to old vertex position (geom).

wrap.applySubset(geom, geomSubset, vertexMapping)

Replace some vertex coordinates from geom by vertex coordinates from geomSubset according to vertexMapping

Parameters:

geom : wrap.Geom

Input geometry.

geomSubset : wrap.Geom

geometry which contains polygons from geom according to polygonIndices.

vertexMapping : list of int

mapping from new vertex positions (from geomSubset) to old vertex position (geom).

wrap.transferPolygroups(geomFrom, geomTo)

Transfer polygroups from geomFrom onto geomTo

Parameters:

geomFrom : wrap.Geom

Input geometry. Should contain polygroups

geomTo : wrap.Geom

Output geometry. Polygroups from geomTo will be replaced with polygroups from geomFrom.

wrap.latticeDeform(geomTarget, geomSource, geomReference, radius)

Deforms geomTarget based on how you reshape control geometry (geomSource and geomReference).

Parameters:

geomTarget : wrap.Geom

Input geometry. Target to deformation.

geomSource : wrap.Geom

Initial control geometry.

geomReference : wrap.Geom

Deformed control geometry.

radius : float

Specifies radius of control points.

Returns:

result : wrap.Geom

result is copy of geomTarget but vertex positions deformed according to input deformation.

wrap.computeBlendShape(neutralGeom, targetGeoms, targetWeights, neutralTexture = [], targetTextures = [])

Compute blendshape with specific weights.

Parameters:

neutralGeom : wrap.Geom

Neutral geometry

targetGeoms : list of wrap.Geom

List of target geometries. Number of vertices of each target must match to the number of vertices of neutral geometry.

targetWeigths : list of float

List of target weights represented as floats.

neutralTexture : wrap.Image

Texture of neutral geometry

targetTextures : list of wrap.Image

List of target textures. Format and dimensions of each target texture must match to neutral texture.

Returns:

result : wrap.Matrix4x4

Returns matrix 4x4 that will transform geomFloating to geomFixed.

Examples

To compute blendshape with textures interpolated:

# specify names and weights
neutralGeomFilename = 'Neutral.obj'
neutralTextureFilename = 'Neutral.jpg'
targetGeomFilenames = ['Fear.obj','Pain.obj','Smile.obj']
targetTextureFilenames = ['Fear.jpg','Pain.jpg','Smile.jpg']
targetWeights = [0.14, 0.61, 0.87]

# loading models
neutralGeom = wrap.Geom(wrap.demoModelsPath + '/Blendshapes/' + neutralGeomFilename)
neutralGeom.texture = wrap.Image(wrap.demoModelsPath + '/Blendshapes/' + neutralTextureFilename)
targetGeoms = [ wrap.Geom(wrap.demoModelsPath + '/Blendshapes/' + filename) for filename in targetGeomFilenames ]
targetTextures = [ wrap.Image(wrap.demoModelsPath + '/Blendshapes/' + filename) for filename in targetTextureFilenames ]

# hiding neutral and target geoms to make visible only blendshape
neutralGeom.hide()
for targetGeom in targetGeoms: targetGeom.hide()

# computing blendshape
blendshapeGeom = wrap.computeBlendShape(neutralGeom, targetGeoms, targetWeights, neutralGeom.texture, targetTextures)

And if you need only geometry without textures just not pass texture parameters:

# computing blendshape
blendshapeGeom = wrap.computeBlendShape(neutralGeom, targetGeoms, targetWeights)
wrap.extractMarvelousAvatar(avatarFileName)

Extract Marvelous Designer avatar (.AVT) into wrap.Geom.

Parameters:

avatarFileName : string

Avatar filename

Returns:

result : wrap.Geom

Returns geometry which contains body of avatar.

wrap.embedMarvelousAvatar(geom, referenceAvatarFileName, wrappedAvatarFileName, neighbourhoodSize = 300)

Embed intance of wrap.Geom into Marvelous Designer avatar (.AVT) file.

Note that reference avatar must be taken from the same version of Marvelous Designer in which the result will be opened. Some versions of Marvalous Designer can not load avatars from others.

Parameters:

geom : wrap.Geom

geometry to embed

referenceAvatarFileName : string

Reference avt-file which will be copied and then body of copy will be replaced by geom.

wrappedAvatarFileName : string

Filename in which output avatar (.AVT) will be stored.

neighbourhoodSize: int

Defines how many neighbour vertices are used to determine bone position. Only used for bones that do not affect skinning.