Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Obi Stitcher 's problem
#1
Pregunta 
When I sewing the two meshes together with obi Stitcher, I could see the bounding box of Obi Solver's solution has changed, but the two meshes did not change. I don't know why.
as figure.
https://lh3.googleusercontent.com/u_mmgF...0-h1005-rw
Reply
#2
(06-08-2020, 12:24 PM)jackdos Wrote: When I sewing the two meshes together with obi Stitcher, I could see the bounding box of Obi Solver's solution has changed, but the two meshes did not change. I don't know why.
as figure.
https://doc-14-04-docs.googleusercontent...11c9gos9be

Hi there,

The link seems empty to me, just a blank screen.
Reply
#3
(06-08-2020, 12:31 PM)josemendez Wrote: Hi there,

The link seems empty to me, just a blank screen.
I have update this link.

(06-08-2020, 12:31 PM)josemendez Wrote: Hi there,

The link seems empty to me, just a blank screen.
Hello,
The new link is https://drive.google.com/file/d/1AbJZp0V...QbPJ4/view
Reply
#4
(06-08-2020, 12:31 PM)josemendez Wrote: Hi there,

The link seems empty to me, just a blank screen.
Hi there,
I added ObiParticleRenderer component to two meshes sewing by ObiStitcher. I can see that the positions of the particles have changed,but the mesh has not changed. What should I do in this case ?
And I look forward to hearing from you. 

as Figure:
https://drive.google.com/file/d/1llMBgE4...sp=sharing
Reply
#5
(07-08-2020, 01:17 PM)jackdos Wrote: Hi there,
I added ObiParticleRenderer component to two meshes sewing by ObiStitcher. I can see that the positions of the particles have changed,but the mesh has not changed. What should I do in this case ?
And I look forward to hearing from you. 

as Figure:
https://drive.google.com/file/d/1llMBgE4...sp=sharing

Hi,

Without a more in-depth description of your setup, I cannot know what's going wrong. My best guess is that you've not added a ObiClothRenderer component to your cloth? That's the only possible cause for the mesh and the particles to be out of sync.
Reply
#6
(07-08-2020, 01:20 PM)josemendez Wrote: Hi,

Without a more in-depth description of your setup, I cannot know what's going wrong. My best guess is that you've not added a ObiClothRenderer component to your cloth? That's the only possible cause for the mesh and the particles to be out of sync.
Hi,
this is some setup of my Obi Cloth
https://drive.google.com/drive/folders/1...sp=sharing

(07-08-2020, 01:20 PM)josemendez Wrote: Hi,

Without a more in-depth description of your setup, I cannot know what's going wrong. My best guess is that you've not added a ObiClothRenderer component to your cloth? That's the only possible cause for the mesh and the particles to be out of sync.
Some codes:

Code:
    private IEnumerator StitchCloth()
    {
        if (sewingIndexA != null
            && sewingIndexB != null
            && sewingIndexA.Count > 0
            && sewingIndexB.Count > 0)
        {
            GameObject stitchObj = new GameObject("Stitch Object");
            stitchObj.transform.SetParent(transform);
            meshA.transform.SetParent(stitchObj.transform);
            meshB.transform.SetParent(stitchObj.transform);

            meshA.gameObject.AddComponent<ObiCloth>();
            meshA.gameObject.AddComponent<ObiClothRenderer>();
            meshB.gameObject.AddComponent<ObiCloth>();
            meshB.gameObject.AddComponent<ObiClothRenderer>();

            // generate blueprintA:
            var blueprintA = ScriptableObject.CreateInstance<ObiClothBlueprint>();
            blueprintA.inputMesh = meshA.mesh;
            yield return StartCoroutine(blueprintA.Generate());
            ObiCloth clothA = meshA.GetComponent<ObiCloth>();
            clothA.clothBlueprint = blueprintA;

            // generate blueprintB:
            var blueprintB = ScriptableObject.CreateInstance<ObiClothBlueprint>();
            blueprintB.inputMesh = meshB.mesh;
            yield return StartCoroutine(blueprintB.Generate());
            ObiCloth clothB = meshB.GetComponent<ObiCloth>();
            clothB.clothBlueprint = blueprintB;

            // sew both sides together:
            ObiStitcher stitcher = stitchObj.AddComponent<ObiStitcher>();
            stitcher.Actor1 = clothA;
            stitcher.Actor2 = clothB;
            for (int i = 0; i < sewingIndexA.Count; i++)
            {
                stitcher.AddStitch(sewingIndexA[i], sewingIndexB[i]);
            }

            // adjust bending constraints to obtain a little less rigid fabric:
            InitClothParameters(clothA);
            InitClothParameters(clothB);

            // push stitcher index to the solver
            stitcher.PushDataToSolver();
        }
    }

    private void InitClothParameters(ObiCloth cloth)
    {
        ObiParticleRenderer particleRD = cloth.gameObject.AddComponent<ObiParticleRenderer>();
        particleRD.shader = Shader.Find("Obi/Particles");
        cloth.selfCollisions = true;
        cloth.maxBending = 0.04f;

        cloth.volumeConstraintsEnabled = false;
        cloth.aerodynamicsEnabled = false;
        cloth.tetherConstraintsEnabled = false;
        cloth.maxCompression = 0.2f;

        for (int i = 0; i < cloth.blueprint.principalRadii.Length; i++)
        {
            cloth.blueprint.principalRadii[i] = Vector3.one * 0.3f;
        }
    }

I don't think there's a problem with that.
Reply
#7
(07-08-2020, 01:32 PM)jackdos Wrote: Hi,
this is some setup of my Obi Cloth
https://drive.google.com/drive/folders/1...sp=sharing

Some codes:

Code:
    private IEnumerator StitchCloth()
    {
        if (sewingIndexA != null
            && sewingIndexB != null
            && sewingIndexA.Count > 0
            && sewingIndexB.Count > 0)
        {
            GameObject stitchObj = new GameObject("Stitch Object");
            stitchObj.transform.SetParent(transform);
            meshA.transform.SetParent(stitchObj.transform);
            meshB.transform.SetParent(stitchObj.transform);

            meshA.gameObject.AddComponent<ObiCloth>();
            meshA.gameObject.AddComponent<ObiClothRenderer>();
            meshB.gameObject.AddComponent<ObiCloth>();
            meshB.gameObject.AddComponent<ObiClothRenderer>();

            // generate blueprintA:
            var blueprintA = ScriptableObject.CreateInstance<ObiClothBlueprint>();
            blueprintA.inputMesh = meshA.mesh;
            yield return StartCoroutine(blueprintA.Generate());
            ObiCloth clothA = meshA.GetComponent<ObiCloth>();
            clothA.clothBlueprint = blueprintA;

            // generate blueprintB:
            var blueprintB = ScriptableObject.CreateInstance<ObiClothBlueprint>();
            blueprintB.inputMesh = meshB.mesh;
            yield return StartCoroutine(blueprintB.Generate());
            ObiCloth clothB = meshB.GetComponent<ObiCloth>();
            clothB.clothBlueprint = blueprintB;

            // sew both sides together:
            ObiStitcher stitcher = stitchObj.AddComponent<ObiStitcher>();
            stitcher.Actor1 = clothA;
            stitcher.Actor2 = clothB;
            for (int i = 0; i < sewingIndexA.Count; i++)
            {
                stitcher.AddStitch(sewingIndexA[i], sewingIndexB[i]);
            }

            // adjust bending constraints to obtain a little less rigid fabric:
            InitClothParameters(clothA);
            InitClothParameters(clothB);

            // push stitcher index to the solver
            stitcher.PushDataToSolver();
        }
    }

    private void InitClothParameters(ObiCloth cloth)
    {
        ObiParticleRenderer particleRD = cloth.gameObject.AddComponent<ObiParticleRenderer>();
        particleRD.shader = Shader.Find("Obi/Particles");
        cloth.selfCollisions = true;
        cloth.maxBending = 0.04f;

        cloth.volumeConstraintsEnabled = false;
        cloth.aerodynamicsEnabled = false;
        cloth.tetherConstraintsEnabled = false;
        cloth.maxCompression = 0.2f;

        for (int i = 0; i < cloth.blueprint.principalRadii.Length; i++)
        {
            cloth.blueprint.principalRadii[i] = Vector3.one * 0.3f;
        }
    }

I don't think there's a problem with that.

Hi there,

There seems to be nothing wring with your setup, or with the code you shared. Except that changing the blueprint once you've instantiated the cloth objects will have no effect at all (like you do here):
Code:
for (int i = 0; i < cloth.blueprint.principalRadii.Length; i++)
        {
            cloth.blueprint.principalRadii[i] = Vector3.one * 0.3f;
        }

Can you share the full source code of your CursorStitch component?

Also, are there any errors popping up in the console?
Reply
#8
(07-08-2020, 02:36 PM)josemendez Wrote: Hi there,

There seems to be nothing wring with your setup, or with the code you shared. Except that changing the blueprint once you've instantiated the cloth objects will have no effect at all (like you do here):
Code:
for (int i = 0; i < cloth.blueprint.principalRadii.Length; i++)
        {
            cloth.blueprint.principalRadii[i] = Vector3.one * 0.3f;
        }

Can you share the full source code of your CursorStitch component?

Also, are there any errors popping up in the console?
HI,this is my demo project with the CursorStitch Component.CursorStitchDemo
steps:
1. press Play;
2. press the left mouse button, to select the sewing area between the two patches;
3. press R key, to flip the points on the second patch;
4. press S key, to sewing the two patches.
Reply
#9
(10-08-2020, 11:21 AM)jackdos Wrote: HI,this is my demo project with the CursorStitch Component.CursorStitchDemo
steps:
1. press Play;
2. press the left mouse button, to select the sewing area between the two patches;
3. press R key, to flip the points on the second patch;
4. press S key, to sewing the two patches.

Hi there,

In your OnDrawGizmos method, you're constantly doing the equivalent to this:

Code:
for (int i = 0; i < count; i++)
meshFilter.mesh.vertices[i]

This is extremely slow, creates a lot of garbage (as you're requesting a copy of all mesh vertices every iteration of the for loop, that the GC has to collect) and will also result in incorrect behavior as you're creating a new instance of the cloth mesh by calling meshFilter.mesh instead of meshFilter.sharedMesh. This is clearly stated in Unity's documentation:

https://docs.unity3d.com/ScriptReference...-mesh.html
Quote:If a mesh is assigned to the mesh filter already, then first query of mesh property will create a duplicate of it, and this copy will be returned. Further queries of mesh property will return this duplicated mesh instance. Once mesh property is queried, link to the original shared mesh is lost and MeshFilter.sharedMesh property becomes an alias to mesh. If you want to avoid this automatic mesh duplication, use MeshFilter.sharedMesh instead.

Calling meshFilter.mesh completely ditches the deformed mesh created by Obi and replaces it with a copy of the original, undeformed mesh. That's why you don't see the mesh moving at all.

Instead, you want something that looks like this:

Code:
// grab the original mesh (not a copy of it) and request a copy of its vertices, only once.
Vector3[] vertices = meshA.sharedMesh.vertices;

// reuse our copy of the vertices for all iterations:
for (int i = 0; i < gatherA.Count; i++)
{
      Vector3 p1 = meshA.transform.TransformPoint(vertices[gatherA[i].v1]);
      Vector3 p2 = meshA.transform.TransformPoint(vertices[gatherA[i].v2]);
      Gizmos.DrawLine(p1, p2);
}

Same for meshB.
Reply
#10
(10-08-2020, 12:18 PM)josemendez Wrote: Hi there,

In your OnGizmos method, you're constantly doing the equivalent to this:

Code:
for (int i = 0; i < count; i++)
meshFilter.mesh.vertices[i]

This is extremely slow, creates a lot of garbage (as you're requesting a copy of all vertices of the mesh every iteration fo the for loop, that the GC has to collect) and will also result in incorrect behavior as you're creating a new instance of the cloth mesh by calling meshA.mesh instead of meshA.sharedMesh. This is clearly stated in Unity's documentation:

https://docs.unity3d.com/ScriptReference...-mesh.html

Calling meshFilter.mesh completely ditches the deformed mesh created by Obi and replaces it with a copy of the original, undeformed mesh. That's why you don't see the mesh moving at all.

Instead, you want something that looks like this:

Code:
// grab the original mesh (not a copy of it) and request a copy of its vertices, only once.
Vector3[] vertices = meshA.sharedMesh.vertices;

// reuse our copy of the vertices for all iterations:
for (int i = 0; i < gatherA.Count; i++)
{
      Vector3 p1 = meshA.transform.TransformPoint(vertices[gatherA[i].v1]);
      Vector3 p2 = meshA.transform.TransformPoint(vertices[gatherA[i].v2]);
      Gizmos.DrawLine(p1, p2);
}

Same for meshB.
Thank you very much, you help me a lot.
In the future, I will pay attention to these programming details, and strive to write high-quality code.
Cheers.
Reply