Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.

First time visiting? Here are some places to start:
  1. Looking for a certain topic? Check out the categories filter or use Search (upper right).
  2. Need support? Ask a question to our Community Support category.
  3. Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
  4. Be respectful, on topic and if you see a problem, Flag it.

If you would like to contact our Community Manager personally, feel free to send a private message or an email.

How to join/knit adjacent surface bodies? joinSurfaceBodies?

mahirmahir Member, Developers Posts: 1,307 ✭✭✭✭✭
I'm trying to work around the shortcomings of using opBoolean to intersect multiple surfaces. To do this I've enlisted the help of opSplit, which has its own restrictions. Specifically, the target query can only contain one body. This is problematic when trying to find the intersection of a group of tool faces/bodies with a group of target faces/bodies. Instead of performing multiple splits on each combination/permutation of tool body vs target body, the easiest fix would be to combine all tools into one cohesive body, all targets into another body, and perform a split using those two surface bodies. Problem is I haven't found a way to implement this.

OS has an internal joinSurfaceBodies() function, but it's not exactly intuitive how to generate all the required inputs (matches, reconstructOp, etc). I hope this makes sense. I'd link to an example, but since it's not working it wouldn't be much help.
Tagged:

Best Answers

  • mahirmahir Member, Developers Posts: 1,307 ✭✭✭✭✭
    edited May 2018 Answer ✓
    For those that read this later, @mbartlett21's featurescript allows opBoolean to successfully perform a Union on adjacent surface bodies by computing matching edges with the following function. It's an elegant implementation and simpler than OS's createMatchesForSurfaceJoin().

    function computeMatches(context is Context, id is Id, tools is Query) returns array
    {
        var partsToDelete = qNothing();
        var returnArray = [];
        const allParts = evaluateQuery(context, tools);
        for (var i = 0; i < size(allParts); i += 1)
        {
            for (var j = i; j < size(allParts); j += 1)
            {
                if (i == j)
                {
                    continue;
                }
                var matchMap = {};
                var parts = qUnion([allParts[i], allParts[j]]);
                const booleanId = id + ("boolean" ~ i ~ "_" ~ j);
                try silent
                {
                    opBoolean(context, booleanId, {
                                "tools" : parts,
                                "operationType" : BooleanOperationType.INTERSECTION,
                                "keepTools" : true,
                                "allowSheets" : true,
                                "eraseImprintedEdges" : false
                            });
                    partsToDelete = qUnion([partsToDelete, qCreatedBy(booleanId, EntityType.BODY)]);
                    var intersections = evaluateQuery(context, qCreatedBy(booleanId));
                    for (var intersection in intersections)
                    {
                        // debug(context, qCreatedBy(booleanId));
                        var allVertices = evaluateQuery(context, qOwnedByBody(intersection, EntityType.VERTEX));
                        for (var k = 0; k < size(allVertices); k += 1)
                        {
                            for (var l = k; l < size(allVertices); l += 1)
                            {
                                if (k == l)
                                {
                                    continue;
                                }
                                var vertex0 = evVertexPoint(context, {
                                        "vertex" : allVertices[k]
                                    });
                                var vertex1 = evVertexPoint(context, {
                                        "vertex" : allVertices[l]
                                    });
                                var matchingEdges = qContainsPoint(qContainsPoint(qOwnedByBody(parts, EntityType.EDGE), vertex0), vertex1);
                                if (size(evaluateQuery(context, matchingEdges)) == 2)
                                {
                                    matchMap = {
                                            "topology" : matchingEdges,
                                            "matchType" : TopologyMatchType.COINCIDENT
                                        };
                                    returnArray = append(returnArray, matchMap);
                                }
                            }
                        }
                    }
                }
            }
        }

Answers

  • mahirmahir Member, Developers Posts: 1,307 ✭✭✭✭✭
    Thanks, @mbartlett21. I should be able to dissect your FS for what I need.
  • mahirmahir Member, Developers Posts: 1,307 ✭✭✭✭✭
    edited May 2018 Answer ✓
    For those that read this later, @mbartlett21's featurescript allows opBoolean to successfully perform a Union on adjacent surface bodies by computing matching edges with the following function. It's an elegant implementation and simpler than OS's createMatchesForSurfaceJoin().

    function computeMatches(context is Context, id is Id, tools is Query) returns array
    {
        var partsToDelete = qNothing();
        var returnArray = [];
        const allParts = evaluateQuery(context, tools);
        for (var i = 0; i < size(allParts); i += 1)
        {
            for (var j = i; j < size(allParts); j += 1)
            {
                if (i == j)
                {
                    continue;
                }
                var matchMap = {};
                var parts = qUnion([allParts[i], allParts[j]]);
                const booleanId = id + ("boolean" ~ i ~ "_" ~ j);
                try silent
                {
                    opBoolean(context, booleanId, {
                                "tools" : parts,
                                "operationType" : BooleanOperationType.INTERSECTION,
                                "keepTools" : true,
                                "allowSheets" : true,
                                "eraseImprintedEdges" : false
                            });
                    partsToDelete = qUnion([partsToDelete, qCreatedBy(booleanId, EntityType.BODY)]);
                    var intersections = evaluateQuery(context, qCreatedBy(booleanId));
                    for (var intersection in intersections)
                    {
                        // debug(context, qCreatedBy(booleanId));
                        var allVertices = evaluateQuery(context, qOwnedByBody(intersection, EntityType.VERTEX));
                        for (var k = 0; k < size(allVertices); k += 1)
                        {
                            for (var l = k; l < size(allVertices); l += 1)
                            {
                                if (k == l)
                                {
                                    continue;
                                }
                                var vertex0 = evVertexPoint(context, {
                                        "vertex" : allVertices[k]
                                    });
                                var vertex1 = evVertexPoint(context, {
                                        "vertex" : allVertices[l]
                                    });
                                var matchingEdges = qContainsPoint(qContainsPoint(qOwnedByBody(parts, EntityType.EDGE), vertex0), vertex1);
                                if (size(evaluateQuery(context, matchingEdges)) == 2)
                                {
                                    matchMap = {
                                            "topology" : matchingEdges,
                                            "matchType" : TopologyMatchType.COINCIDENT
                                        };
                                    returnArray = append(returnArray, matchMap);
                                }
                            }
                        }
                    }
                }
            }
        }

  • mahirmahir Member, Developers Posts: 1,307 ✭✭✭✭✭
    Lost track of the }'s :)
  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 2,048 ✭✭✭✭✭
    @mahir
    It now finds even more matches
    mb - draftsman - also FS author: View FeatureScripts
    IR for AS/NZS 1100
Sign In or Register to comment.