Checking the Tangency of All Surfaces in Ansys SpaceClaim

Categories:

The other day we got a tech support request wanting to know to check the tangency of all the surfaces in a model systematically in Ansys SpaceClaim. You can check surface tangency at an edge using the Measure > Dihedral tool. This measures the angle between the surfaces at a given number of points along the edge and returns the maximum and minimum values.  If the surfaces are tangent, then the dihedral is zero. If not, scaled lines will show the dihedral values at the evaluated points.

Checking the Tangency in Ansys SpaceClaim, Figure 1
Ansys

This works great for a few edges, but checking the whole model would be quite tedious. So we turn to SpaceClaim Scripting.  After checking the current scripting API and realizing that the dihedral calculation is not yet available, I wrote my own. You can download the script here. The script checks the dihedral value of each edge and returns the active set of the non-tangent edges. Since we would also have many edges that we already know are not tangent, like 90° angles, the script includes a cutoff angle of 40°.  Only edges with a minimum dihedral below the cutoff angle will be selected.

# Python Script, API Version = V19

#############################################################
# tangency_check.py
# Select the geometry to check and then run the script
# Author: Joe Woodward
#         Chief Engineer - Simulation Support
#         Phoenix Analysis and Design technologies
#  1/31/2023
##############################################################

maximum_angle_cutoff=25  #Curves with a minimum angle larger than this will not be selected.
minimum_angle_cutoff=0 #1e-3  #Curves with a maximum angle smaller than this will not be selected.
numpoints=10  #Number of of curve evaluation points
print_edges=0 #Change to 1 to print max,min dihedral values for all non-tangent edges
#Selecting edges, or rerunning script with edges selected will also print the values.

from math import acos,sqrt,degrees

def angle(v1,v2):
    x1,y1,z1=v1
    x2,y2,z2=v2
    
    lenSq1 = x1*x1 + y1*y1 + z1*z1
    lenSq2 = x2*x2 + y2*y2 + z2*z2
    dot = x1*x2 + y1*y2 + z1*z2    #between [x1, y1, z1] and [x2, y2, z2]
    
    if lenSq1==0 or lenSq2==0:
        #print("Normal has zero length",lenSq1,lenSq2)
        return None
    try:
        rads=dot/sqrt(lenSq1 * lenSq2)
        angle = degrees(acos(rads))
        #print(dot,lenSq1,lenSq2,rads,angle)
    except ValueError:
        rads=round(dot/sqrt(lenSq1 * lenSq2),8)
        angle = degrees(acos(rads))
        #print("AgainAgain",dot,lenSq1,lenSq2,rads,angle)
    except ZeroDivisionError:
          print("ZeroRadians",dot,lenSq1,lenSq2)
        
        
    if angle>90: return 180-angle
    return angle


def dihedral_maxmin(edge,numevals=numpoints,problems=[]):
    angles=[]
    for ratio in [x*1.0/numevals for x in range(numevals+1)]:
        edge_p=edge.EvalProportion(ratio).Point
        edge_faces=edge.Faces
        n1=edge_faces[0].Shape.ProjectPoint(edge_p).Normal
        n2=edge_faces[1].Shape.ProjectPoint(edge_p).Normal
        ang1=angle(n1,n2)
        if ang1==None:
            print("Normal has zero length at ratio %4.2f"%ratio,n1,n2)
            problems.append(edge)
            return None,None
        angles.append(ang1)
    return max(angles),min(angles)

#Algorithm to get the interior curves of the current surface patch
#faces=Selection.CreateByObjects([GetRootPart().Bodies[0].Faces[1].GetConnection(0)])
#otherfaces=faces.GetInverse()
#otheredges=otherfaces.ConvertToEdges()
#edges=otheredges.GetInverse()

#Check current selection for geometry types.
current_selection=Selection.GetActive()
        
if current_selection.FilterFaces().Count!=0:
    current_faces=current_selection.FilterFaces()
    check_edges=current_faces.ConvertToEdges()
elif current_selection.FilterEdges().Count!=0:
    check_edges=current_selection.ConvertToEdges()
    print_edges=1 #If only edges are picked, then print the dihedrals
elif current_selection.FilterBodies().Count!=0:
    current_bodies=current_selection.FilterBodies()
    check_edges=current_bodies.ConvertToEdges()
elif current_selection.FilterComponents().Count!=0:
    check_edges=current_selection.ConvertToEdges()
else:
    bodies=BodySelection.Create(GetRootPart().GetAllBodies())
    all_faces=bodies.ConvertToFaces()
    all_edges=all_faces.ConvertToEdges()
    check_edges=all_faces.ConvertToEdges()

start_count=check_edges.Count 
nontangents=[]
problems=[]

for edge in check_edges.Edges:
    #esel=EdgeSelection.Create(edge) #Uncomment these lines to see the lines
    #esel.SetActive()                            #as they are checked.
    edge_dihedral_max,edge_dihedral_min=dihedral_maxmin(edge,problems=problems)
    if edge_dihedral_max==None:
        continue
    if edge_dihedral_min>=maximum_angle_cutoff:continue

    if edge_dihedral_max<=minimum_angle_cutoff:continue

    if print_edges==1:
        print(edge_dihedral_max,edge_dihedral_min)
    nontangents.append(edge)
    
nontangent_selection=EdgeSelection.Create(nontangents)
nontangent_selection.SetActive()

print("%d edges processed. %d edges have dihedrals between %f and %f degrees."%(start_count,len(nontangents),minimum_angle_cutoff,maximum_angle_cutoff))
if print_edges==0:
    print("NonTangent edges are now selected. Rerun the script to print the maximum,minimum dihedrals for those edges.")

if len(problems)>0:
    print("The script had problems with %d edges. They should now be highlighted in blue."%len(problems))
    problemSelection=EdgeSelection.Create(problems)
    problemSelection.SetActiveSecondary()

Here is the file for download:

I was writing this for the customer in Ansys SpaceClaim 2020R2, which does not import numpy, so I had to write my own angle calculation function. I am happy to report, though, that SpaceClaim 2023R1 does import numpy, so now all of its amazing functions can be used.

Video Showing how to Check Tangency in Ansys SpaceClaim

Here is a quick video explaining the script and how to attach the script to your Toolbar for quick use whenever it’s needed.

Get Your Ansys Products & Support from the Engineers who Contribute to this Blog.

Technical Expertise to Enable your Additive Manufacturing Success.

Share this post:

Upcoming Events

Aug 13
, 2026
From Hours to Minutes: Accelerate Your Designs with Zemax HPC - Webinar
Aug 14
, 2026
Ansys Fluent Meshing Watertight Geometry Workflow - Webinar
Aug 20
, 2026
AZBio Spring Reception
Aug 23
- Aug 26
, 2026
Small Satellite Conference 2026
Aug 24
- Aug 27
, 2026
Nuclear Energy Conference & Expo - 2026
Aug 26
, 2026
Ansys Simulation Solutions for Pumps, Compressors and Fans - Webinar
Sep 14
- Sep 19
, 2026
IMTS 2026
Oct 07
, 2026
2026 AZBio Awards
Oct 08
, 2026
White Hat Life Science Investor Conference
Oct 21
, 2026
2026 Southern Arizona Tech + Business Expo
Oct 28
, 2026
Nerdtoberfest 2026
Nov 18
, 2026
2026 Governor’s Celebration of Innovation

Contact Us

Most of our customers receive their support over the phone or via email. Customers who are close by can also set up a face-to-face appointment with one of our engineers.

For most locations, simply contact us: