Project

General

Profile

Mesh from Strands Modifier » Test_MeshFromStrandsModifier.ms

Marsel Khadiyev, 08/23/2014 07:41 AM

 
struct Test_MeshFromStrandsModifier
(
-- Tests that a distribution map can be assigned to control which proxy mesh is used for which strand in Mesh From Strands modifier
function Test_ProxyDistributionMap =
(
-- Create a plane with 3x3 segments (so that there are are no vertices going exactly down the middle)
distributionObject = Plane lengthsegs:3 widthsegs:3

-- Create a simple box and another plane, we'll use these as proxy meshes
boxProxy = Box lengthsegs:1 widthsegs:1 heightsegs:1
planeProxy = Plane lengthsegs:1 widthsegs:1

max modify mode

-- Add guides from surface modifier and make sure we'll use vertices to generate strands, so that we always have a predictable strand count
select distributionObject
modPanel.addModToSelection (Ox_Guides_from_Surface())
distributionObject.modifiers[#Ox_Guides_from_Surface].method = 4

-- Add "Ox Mesh From Strands" modifier
modPanel.addModToSelection (Ox_Mesh_from_Strands())
$.modifiers[#Ox_Mesh_from_Strands].type = 2

-- Add the two proxy objects
$.modifiers[#Ox_Mesh_from_Strands].addproxyobject boxProxy
$.modifiers[#Ox_Mesh_from_Strands].addproxyobject planeProxy

-- Assign a new checkers texture to the proxy map slot
$.modifiers[#Ox_Mesh_From_Strands].proxyDistributionMap = Checker ()

-- TODO: Add some assertions

-- Cleanup
delete distributionObject
delete boxProxy
delete planeProxy
),

-- When Edit Normals modifier is applied to a proxy object and normals are edited, the custom normals should also appear in the resulting hair mesh
function Test_ProxyCustomNormalsAreCopied =
(
distributionObject = Plane()
distributionObject.width = 50
distributionObject.length = 50
proxyPlane = Plane lengthsegs:1 widthsegs:1
proxyPlane.width = 50
proxyPlane.length = 50

max modify mode

-- Edit the proxy plane normals to all point up
select proxyPlane
modPanel.addModToSelection (Edit_Normals())
editNormalsModifier = $.modifiers[1]
editNormalsModifier.Select #{1..4}
editNormalsModifier.Move [100, 100, 0]

-- Set up the mesh from strands modifier
-- Add guides from surface modifier and make sure we'll use vertices to generate strands, so that we always have a predictable strand count
select distributionObject
guidesFromSurfaceModifier = Ox_Guides_from_Surface()
TestUtilities.SetGuidesFromMeshDefaults guidesFromSurfaceModifier
guidesFromSurfaceModifier.count = 1
modPanel.addModToSelection guidesFromSurfaceModifier

-- Add "Ox Mesh From Strands" modifier
meshFromStrandsModifierInstance = Ox_Mesh_from_Strands()
meshFromStrandsModifierInstance.type = 2
meshFromStrandsModifierInstance.addproxyobject proxyPlane
meshFromStrandsModifierInstance.uniScale = off
modPanel.addModToSelection meshFromStrandsModifierInstance

-- Make sure the normals in the resulting mesh are the same as the normals in the proxy mesh
modPanel.addModToSelection (Edit_Normals())
resultEditNormalsModifier = $.modifiers[#Edit_Normals]
firstNormal = resultEditNormalsModifier.getnormal 1

-- The resulting vector should not point directly up, down, etc.
EAssert.AreNotNearEqual 0.0 firstNormal.x
EAssert.AreNotNearEqual 1.0 firstNormal.x
EAssert.AreNotNearEqual 0.0 firstNormal.y
EAssert.AreNotNearEqual 1.0 firstNormal.y
EAssert.AreNotNearEqual 0.0 firstNormal.z
EAssert.AreNotNearEqual 1.0 firstNormal.z
-- Cleanup
delete distributionObject
delete proxyPlane
),

function Test_TwistChannel =
(
distributionObject = Plane lengthsegs:1 widthsegs:1

max modify mode

-- Set up the mesh from strands modifier, use per vertex distribution
select distributionObject
-- Guides from surface modifier with vertex distribution and 2 points per strand
guidesFromSurfaceModifier = Ox_Guides_from_Surface()
modPanel.addModToSelection guidesFromSurfaceModifier
guidesFromSurfaceModifier.method = 4
guidesFromSurfaceModifier.NumSegs = 2
editGuidesModifier = Ox_Edit_Guides()
modPanel.addModToSelection editGuidesModifier

-- Create a twist channel
twistChannelIndex = editGuidesModifier.CreateChannel true "TwistChannel"
editGuidesModifier.SelectRoots #{1..4}

-- Add mesh from strands modifier with bollboard setting and apply the twist channel to twist
meshFromStrandsModifier = Ox_Mesh_from_Strands()
modPanel.addModToSelection meshFromStrandsModifier
meshFromStrandsModifier.type = 1
meshFromStrandsModifier.twistChan = ( TestUtilities.GetRootChannelIdentifier twistChannelIndex )
meshFromStrandsModifier.twistDir = 1

-- Copy resulting mesh vertices before the twist
verticesBeforeTwist = TestUtilities.GetVertexArray distributionObject.mesh
modPanel.setCurrentObject editGuidesModifier
subobjectLevel = 1
editGuidesModifier.SetChannelValueToSelection true twistChannelIndex 0.2
modPanel.setCurrentObject meshFromStrandsModifier
verticesAfterTwist = TestUtilities.GetVertexArray distributionObject.mesh
-- Make sure that, after we applied the twist channel value, the vertex positions have changed
for i = 1 to verticesBeforeTwist.count do
(
EAssert.AreNotNearEqual verticesBeforeTwist[i].x verticesAfterTwist[i].x
EAssert.AreNotNearEqual verticesBeforeTwist[i].y verticesAfterTwist[i].y
-- The Z coordinate will remain the same since twist is only along one axis
)
-- Cleanup
delete distributionObject
),
function Test_RenderSettingsWidthControlsProxyUniformWidth =
(
distributionObject = Plane lengthsegs:1 widthsegs:1

max modify mode

-- Set up the mesh from strands modifier, use per vertex distribution
select distributionObject
-- Guides from surface modifier with vertex distribution and 2 points per strand, no randomness in length, and strand length of 1
guidesFromSurfaceModifier = Ox_Guides_from_Surface()
modPanel.addModToSelection guidesFromSurfaceModifier
guidesFromSurfaceModifier.method = 4
guidesFromSurfaceModifier.NumSegs = 2
guidesFromSurfaceModifier.randomness = 0
guidesFromSurfaceModifier.guideLength = 1
-- Render settings modifier with global radius of 2
renderSettingsModifier = Ox_Render_Settings()
modPanel.addModToSelection renderSettingsModifier
renderSettingsModifier.radius = 2
-- Mesh from strands modifier with a box proxyobject and uniform scale on
meshFromStrandsModifier = Ox_Mesh_from_Strands()
modPanel.addModToSelection meshFromStrandsModifier
meshFromStrandsModifier.type = 2
meshFromStrandsModifier.uniScale = on
boxProxy = Box lengthsegs:1 widthsegs:1 heightsegs:1
meshFromStrandsModifier.addproxyobject boxProxy
-- Measure the resulting proxy mesh box by comparing the first and fifth vertex Z coordinate, it should have the size of 2
EAssert.AreNearEqual 2 ( distance( distributionObject.mesh.vertices[1].position ) ( distributionObject.mesh.vertices[2].position ) )
-- Change the render settings width to 0.5 and make sure the resulting box sizes change
renderSettingsModifier.radius = 0.5
EAssert.AreNearEqual 0.5 ( distance( distributionObject.mesh.vertices[1].position ) ( distributionObject.mesh.vertices[2].position ) )
-- Cleanup
delete distributionObject
delete boxProxy
)
)

EUnit.AddTestClass Test_MeshFromStrandsModifier
ok
(4-4/6)