Beispiel #1
0
    def __init__(self, w, t, noflap=False):  ## What is w, t and noflap?  ##
        if (noflap or eval_equation(t) > eval_equation(w) /
                2):  ## eval_equation() just a equation to return a value
            Face.__init__(self, ((w, 0), (w, t), (0, t)))
        else:
            Face.__init__(self, ((w, 0), (w + t, 0), (w, t), (0, t), (-t, 0)))
            self.edges['f0'] = DrawingEdge("f0", (0, 0), (0, t), Flex())
            self.edges['f1'] = DrawingEdge("f1", (w, 0), (w, t), Flex())

        self.edges.pop('e0')
        self.transform(origin=(-w / 2.0, -t / 2.))
Beispiel #2
0
def BeamTabSlotHelper(face, faceEdge, thick, widget, **kwargs):
    '''widget is representing TabDrawing or SlotDrawing, means it is a face'''
    coords = face.edge_coords(face.edge_index(faceEdge))
    globalOrigin = coords[0]
    theta = arctan2(coords[1][1] - coords[0][1], coords[1][0] - coords[0][0])
    length = norm((coords[1][1] - coords[0][1], coords[1][0] - coords[0][0]))

    try:
        frac = kwargs['frac']
    except:
        frac = 0.5
    try:
        noflap = kwargs['noflap']
    except:
        noflap = False

    try:
        component = kwargs['component']
        length = float(eval_equation(length))
    except:
        #not sympy
        pass

    n = 0  ## the number of tabs we need. ##
    tw = thick * 3  ## what is tw? ##
    while (eval_equation(tw) > eval_equation(thick) * 2):
        n += 1
        d = length * 1.0 / (n * 5 + 1)
        tw = 2 * d

    t = widget(w=tw, t=thick * frac, noflap=noflap)
    t.transform(angle=pi, origin=(-2 * d, thick / 2.))
    try:
        if kwargs["mirror"]:
            t.mirrorY()
            t.transform(origin=(0, thick))
    except:
        pass

    for i in range(n):
        t.transform(origin=(d * 5, 0))
        for (name, edge) in t.edges.iteritems():
            e = edge.copy()
            e.transform(angle=theta, origin=globalOrigin)
            face.add_decoration(
                (((e.x1, e.y1), (e.x2, e.y2)), e.edge_type.edge_type))
        try:
            if kwargs["alternating"]:
                t.mirrorY()
                t.transform(origin=(0, thick))
        except:
            pass
 def __init__(self, length, male=True, **kwargs):
     coords = CoorForFingerjoint(eval_equation(length), male)
     edge_names = ["e%d" % i for i in range(len(coords))]
     edge_names[2] = "attachedge"
     Face.__init__(self,
                   'finger_joint',
                   coords, [NON_PARAM_LEN for x in coords],
                   edge_names=edge_names)
Beispiel #4
0
 def __init__(self, length, width, male=False, **kwargs):
     coordsOfFinger = maleFemaleFingerJointDrawing(eval_equation(length),
                                                   width, male)
     edge_names = ["e%d" % i for i in range(len(coordsOfFinger))]
     edge_names[2] = "slotedge"
     Face.__init__(self,
                   'ffinger_joint',
                   coordsOfFinger, [NON_PARAM_LEN for x in coordsOfFinger],
                   edge_names=edge_names)
Beispiel #5
0
    def eval_hierarchical_constraints(self):
        """Evaluates all the constraints imposed on subcomponents

        Args:
            None

        """
        for (var, val) in self.hierarchical_constraints.iteritems():
            var.set_solved(eval_equation(val))
Beispiel #6
0
    def to_stl(self, filename):
        """
      Converts the graph to STL

      Args:
          filename (str): name of file to write STL data to
      """
        self.place()
        stlFaces = []
        for face in self.faces:
            if eval_equation(face.area) > 0:
                tdict = copy.deepcopy(face.get_triangle_dict())
                newverts = []
                for vert in tdict["vertices"]:
                    newverts.append(tuple(eval_equation(i) for i in vert))
                tdict["vertices"] = newverts
                stlFaces.append(
                    [eval_equation(face.transform_3D), tdict, face.name])
            '''
        else:
          print "skipping face:", face.name
        '''
        stl_write(stlFaces, filename)
Beispiel #7
0
def maleFemaleFingerJointDecoration(face,
                                    faceEdge,
                                    thick,
                                    widget,
                                    male=True,
                                    **kwargs):
    """
    help to find how many fingers we need for different subcomponent.And add these fingers into the face.
    :param face: The face we add decoration;
    :param faceEdge: the edge we refer to;
    :param thick: the width of finger, it usually is 3.0mm.
    :param male: the type of decoration;
    :param widget: a face object to represent the finger;
    :param kwargs: kwargs;
    :return: None. the decoration will be added into selected face after operation
    """
    coords = face.edge_coords(face.edge_index(faceEdge))
    globalOrigin = coords[0]
    theta = arctan2(coords[1][1] - coords[0][1], coords[1][0] - coords[0][0])
    length = norm((coords[1][1] - coords[0][1], coords[1][0] - coords[0][0]))
    length = eval_equation(length)
    try:
        component = kwargs['component']
        length = float(eval_equation(length))
    except:
        # not sympy
        pass

        ## find the number of fingers and create unwanted edges' index.
    widthOfFinger = 5.0  ## the width of finger. ##
    spaceOfEdge = 20.0
    upperLimitOfMD = eval_equation(length) / (2.0 * widthOfFinger) - 2.5
    nOfmFinger = int(eval_equation(upperLimitOfMD))
    if eval_equation(length) < eval_equation(spaceOfEdge +
                                             widthOfFinger * 3.0):
        return "This edge is too short to add finger joint."
    if male:  ##maleFinger
        nOfOFinger = nOfmFinger
    else:
        nOfOFinger = nOfmFinger + 1

    lengthOfSpace = (length - (2 * nOfOFinger - 1) * widthOfFinger) / 2.0
    widthOfFingerForD = widthOfFinger
    widthOfDecoration = widthOfFinger

    t_l = widget(length=eval_equation(lengthOfSpace), width=thick)
    t = widget(length=eval_equation(widthOfDecoration), width=thick)
    t_r = widget(length=eval_equation(lengthOfSpace), width=thick)

    ## for left side space******************
    for (name, edge) in t_l.edges.iteritems():
        e = edge.copy()
        e.transform(angle=theta, origin=globalOrigin)
        face.add_decoration(
            (((e.x1, e.y1), (e.x2, e.y2)), e.edge_type.edge_type))
    try:
        if kwargs["alternating"]:
            t.mirrorY()
            t.transform(origin=(0, thick))
    except:
        pass
    ##****************************

    ## add all of the edges into the face we select ##
    for i in range(1, nOfOFinger):
        if (i == 1):
            movementOfOriginal = eval_equation(widthOfFingerForD +
                                               lengthOfSpace)
        else:
            movementOfOriginal = eval_equation(
                widthOfFingerForD + widthOfDecoration
            )  ## need to revise to be able to fit with assembly
        t.transform(origin=(movementOfOriginal, 0))
        for (name, edge) in t.edges.iteritems():
            e = edge.copy()
            e.transform(angle=theta, origin=globalOrigin)
            face.add_decoration(
                (((e.x1, e.y1), (e.x2, e.y2)), e.edge_type.edge_type))

        try:
            if kwargs["alternating"]:
                t.mirrorY()
                t.transform(origin=(0, thick))
        except:
            pass

    ## for right side space******************
    t_r.transform(origin=((length / 2.0 + widthOfFingerForD * nOfOFinger -
                           widthOfFingerForD / 2.0), 0))
    for (name, edge) in t_r.edges.iteritems():
        e = edge.copy()
        e.transform(angle=theta, origin=globalOrigin)
        face.add_decoration(
            (((e.x1, e.y1), (e.x2, e.y2)), e.edge_type.edge_type))
    try:
        if kwargs["alternating"]:
            t.mirrorY()
            t.transform(origin=(0, thick))
    except:
        pass
Beispiel #8
0
def maleFemaleFingerJointDrawing(l, width, male=True):
    """
    :param l: the length of edge which you want to add finger joint;
    :param width: the width of finger
    :param male: type of finger joint, male or female
    :return: return the coordinates of finger joint face.
    """
    ## create the coordinates for male finger joint. ##

    # thickOfMaterial = 3.0  ## the thickness of material. #
    l = eval_equation(l)
    width = eval_equation(width)
    widthOfFinger = 5.0  ## the width of finger. ##
    spaceOfEdge = 20.0  ## the space left to avoid overlapping in corner, such as cube. ##
    extraSpaceOfFingerJoint = 0.0  ## need calibration ##
    #width = thickOfMaterial# add more parameters for real world assemble. ##
    upperLimitOfM = l / (
        2.0 * widthOfFinger
    ) - 2.5  ## the upper boundary for the number of fingers. ##

    ## calculate the coordinates of finger joint face. ##
    if l < eval_equation(spaceOfEdge + widthOfFinger * 3.0):
        return "This edge is too short to add finger joint."
    else:
        nOfmFinger = int(eval_equation(
            upperLimitOfM))  ## Find out how many fingers we need.##

        ## male or female finger joint. "
    if male:  ##maleFinger
        nOfFinger = nOfmFinger
    else:
        nOfFinger = nOfmFinger + 1
    ## maleFingerDecoration, the number of female fingers must bigger than male by 1. This is the rule. ##

    ## generate the coordinates module for fingerJoint face (male and female are the same). ##
    fingerModule_rb = (
        (l / 2.0 + widthOfFinger * nOfFinger - widthOfFinger / 2.0),
        extraSpaceOfFingerJoint)  ## rb is right and bottom. ##
    fingerModule_rt = (
        (l / 2.0 + widthOfFinger * nOfFinger - widthOfFinger / 2.0),
        extraSpaceOfFingerJoint + width)  ## right and top##
    fingerModule_lt = (
        (l / 2.0 + widthOfFinger * (nOfFinger - 1.0) - widthOfFinger / 2.0),
        extraSpaceOfFingerJoint + width)  ## lt is left and top. ##
    fingerModule_lb = (
        (l / 2.0 + widthOfFinger * (nOfFinger - 1.0) - widthOfFinger / 2.0),
        extraSpaceOfFingerJoint)  ## left and bottom.##
    fingerModule = (fingerModule_rb, fingerModule_rt, fingerModule_lt,
                    fingerModule_lb)

    ## define the coordinates of rest points except the fingers. ##
    coordinatesOfFingerJoint = ((0, extraSpaceOfFingerJoint), (0, 0), (l, 0),
                                (l, extraSpaceOfFingerJoint))
    coordinatesOfFingerSeries = (
    )  ## to save the coordinates of points of fingers. ##

    ## generate coordinates for fingers with a for loop.##
    if nOfFinger == 1:
        coordinatesOfFingerSeries = fingerModule
    else:
        listOfFingerModule = [
            list(x) for x in fingerModule
        ]  ## convert the nested tuple into nested list because tuple is immutable. ##
    for i in range(nOfFinger):
        if i == 0:  ## when i = 0, just append the tuple. ##
            coordinatesOfFingerSeries += fingerModule
        else:  ## substruct 10 every time
            for j in range(len(listOfFingerModule)):
                listOfFingerModule[j][
                    0] = listOfFingerModule[j][0] - 2 * widthOfFinger
            tupleOfFingerModule = tuple(
                tuple(li) for li in listOfFingerModule
            )  ##convert the nested list into nested tuple. ##
            coordinatesOfFingerSeries += tupleOfFingerModule
    return coordinatesOfFingerJoint + coordinatesOfFingerSeries
Beispiel #9
0
def extractFromComponent(c):
    output = {}
    output["solved"] = {
        str(x): x.get_value()
        for x in c.parameters.values() if isinstance(x, Variable)
    }
    print output["solved"]
    output["faces"] = {}
    try:
        graph = {"edges": [], "faces": []}
        graph["edges"] = c.composables['graph'].edges
        graph["faces"] = c.composables['graph'].faces
    except:
        pass

    for i in graph["faces"]:
        #pdb.set_trace()
        tdict = copy.deepcopy(i.get_triangle_dict(separateHoles=True))
        tdict["holes"] = []
        print "Tdict:", tdict
        for vertex in range(len(tdict["vertices"])):
            try:
                tpl = tdict["vertices"][vertex]
                tdict["vertices"][vertex] = [tpl[0], tpl[1]]
                if isinstance(tdict["vertices"][vertex][0], sympy.Basic):
                    tdict["vertices"][vertex][0] = scheme_list(
                        tdict["vertices"][vertex][0])
                if isinstance(tdict["vertices"][vertex][1], sympy.Basic):
                    tdict["vertices"][vertex][1] = scheme_list(
                        tdict["vertices"][vertex][1])
            except:
                try:
                    tdict["vertices"][vertex][1] = scheme_list(
                        tdict["vertices"][vertex][1])
                except:
                    pass
        try:
            for hole in range(len(tdict["hole_vertices"])):
                for vertex in range(len(tdict["hole_vertices"][hole])):
                    try:
                        tpl = tdict["hole_vertices"][hole][vertex]
                        tdict["hole_vertices"][hole][vertex] = [
                            eval_equation(tpl[0]),
                            eval_equation(tpl[1])
                        ]
                        if isinstance(tdict["hole_vertices"][hole][vertex][0],
                                      sympy.Basic):
                            tdict["hole_vertices"][hole][vertex][
                                0] = scheme_list(
                                    tdict["hole_vertices"][hole][vertex][0])
                        if isinstance(tdict["hole_vertices"][hole][vertex][1],
                                      sympy.Basic):
                            tdict["hole_vertices"][hole][vertex][
                                1] = scheme_list(
                                    tdict["hole_vertices"][hole][vertex][1])
                    except:
                        try:
                            tdict["hole_vertices"][hole][vertex][
                                1] = scheme_list(
                                    tdict["hole_vertices"][hole][vertex][1])
                        except:
                            pass
        except:
            pass
        output["faces"][i.name] = [[
            scheme_list(i.transform_3D[x])
            for x in range(getLen(i.transform_3D))
        ], tdict]
        #print i.transform2D.tolist()
        trans2D = [[scheme_list(p) for p in j]
                   for j in getList(i.transform_2D)]
        #print trans2D
        output["faces"][i.name].append(trans2D)
    output["edges"] = {}

    for i in graph["edges"]:
        output["edges"][i.name] = []
        for v in range(2):
            output["edges"][i.name].append([])
            for x in range(3):
                try:
                    if isinstance(i.pts_3D[v][x], sympy.Basic):
                        output["edges"][i.name][v].append(
                            scheme_list(i.pts_3D[v][x]))
                except:
                    pass
    output["interfaceEdges"] = {}
    output["interfaceFaces"] = []
    print c.interfaces
    for k, v in c.interfaces.iteritems():
        ports = c.get_interface(k).get_ports()
        for port in ports:
            if isinstance(port, edge_port.EdgePort):
                output["interfaceEdges"][k] = []
                for i in port.get_edges():
                    try:
                        output["interfaceEdges"][k].append(i)
                    except:
                        pass
            if isinstance(port, face_port.FacePort):
                output["interfaceFaces"].append(k)

    return output
Beispiel #10
0
 def place_faces(self, face, edge_from, transform_2D, placed=None, allow_overlap=False):
     """Recursively adds faces to the 2D drawing.
     Args:
         face: the current face being placed
         edge_from: the edge by which to attach the current face
         transform_2D: A tranformation matrix to move the face into its position in 2D space
         placed: dictionary containing metadata about previously placed entities
         allow_overlap: Whether or not to allow two face to be placed on top of each other
     """
     if placed is not None and face in placed['faces']:
         #This face has already been placed, do not place again
         return
     if placed is None:
         #No faces have been placed yet, initialize data structures
         placed = {'faces': [], 'edges': {}, 'overlapping': []}
         check_for_overlap = not allow_overlap
     else:
         #Overlap checking is handled only in top level call
         check_for_overlap = False
     """
     Placing faces involves the notion of "pretransformed" and "transformed" values.
     Pretransformation moves the edge a face is being connected by to the x axis,
     and can be thought of as a face's relative position to its neighbor.
     Transformation moves a face to its absolute position in 2D space.
     """
     if edge_from is not None:
         #Align connected edges
         pretransform_matrix = face.pre_transform(edge_from)
     else:
         #Place edge as is
         pretransform_matrix = np.eye(4)
     transform_matrix = np.dot(transform_2D, pretransform_matrix)
     #4D pts are the homogenous coordinates of the face i.e. [x,y,z,1]
     pretransformed_pts_4D = np.dot(pretransform_matrix, face.pts_4D)
     transfromed_pts_4D = np.dot(transform_matrix, face.pts_4D)
     pretransformed_pts_2D = pretransformed_pts_4D[0:2,:]
     #Numerical values for the coordinates are required for placement
     transfromed_pts_2D = eval_equation(transfromed_pts_4D[0:2, :])
     if not self.add_face(transfromed_pts_2D):
         #If face cannot be placed without collisions, attempt to reflect it
         reflection_matrix = np.array([[1,  0, 0, 0],
                                       [0, -1, 0, 0],
                                       [0,  0, 1, 0],
                                       [0,  0, 0, 1]])
         #Recompute pretransform and transform with rotation
         pretransform_matrix = np.dot(reflection_matrix, pretransform_matrix)
         transform_matrix = np.dot(transform_2D, pretransform_matrix)
         pretransformed_pts_4D = np.dot(pretransform_matrix, face.pts_4D)
         transfromed_pts_4D = np.dot(transform_matrix, face.pts_4D)
         pretransformed_pts_2D = pretransformed_pts_4D[0:2,:]
         transfromed_pts_2D = eval_equation(transfromed_pts_4D[0:2, :])
         if not self.add_face(transfromed_pts_2D) and not allow_overlap:
             #Face was not able to be placed connected to this edge
             #Keep track of face and hope it gets placed elsewhere
             #TODO: Try connecting along other edges or undoing previous placements?
             placed['overlapping'].append(face)
             return
     #Face is being placed
     placed['faces'].append(face)
     if face in placed['overlapping']:
         placed['overlapping'].remove(face)
     face.transform_2D = transform_matrix
     #Will this break if a face has to be flipped?
     ## find out how to transform the decoration. ##
     for e in face.get_2D_decorations():
             self.edges[e[0]] = DrawingEdge(e[0], [eval_equation(x) for x in e[1]],
                                     [eval_equation(x) for x in e[2]], EdgeType(e[3]))
     ## edges here is a dictionary, the key is decoration edge name. e is nested list and its first element is the edge name. ##
     #Place each edge
     for (i, edge) in enumerate(face.edges):
         #HACK: Do not place temporary edges
         if edge is None or edge.name[:4] == "temp":
             continue
         #Get the endpoints of the edge
         edge_pts_2D = (transfromed_pts_2D[:,i - 1],transfromed_pts_2D[:,i])
         if edge.name in placed['edges'].keys():
             edge_alias = placed['edges'][edge.name]
             if diff_edge(edge_alias, edge_pts_2D,2):
             #If the edge has already been placed in a different place, a cut must be made
             #Create a new edge
                 self.edges['temp' + edge.name] = DrawingEdge('temp' + edge.name, edge_pts_2D[0], edge_pts_2D[1], Cut())
             # Make old edge into a cut
                 self.edges[edge.name] = DrawingEdge(edge.name, edge_alias[0], edge_alias[1], Cut())
         else:
             #Add edge normally
             if len(edge.faces) == 1:
                 edge_type = Cut()
             else:
                 edge_type = Fold()
             self.edges[edge.name] = DrawingEdge(edge.name, edge_pts_2D[0], edge_pts_2D[1], edge_type)
             placed['edges'][edge.name] = edge_pts_2D
         if len(edge.faces) <= 1:
             # No other faces to be found, move on to next edge.
             continue
         if edge.is_tab():
             # Don't follow faces off of a Tab
             continue
         #Compute new transform matrix for next face
         rotation_matrix = rotate_x_to(pretransformed_pts_2D[:,i],pretransformed_pts_2D[:,i-1])
         origin_matrix = move_origin_to(pretransformed_pts_2D[:,i-1])
         next_transfrom_2D = np.dot(transform_2D,np.dot(origin_matrix,np.dot(rotation_matrix,np.eye(4))))
         #Place faces connected to edge
         for(f,a) in edge.faces.iteritems():
             self.place_faces(f, edge, next_transfrom_2D, placed)
     if check_for_overlap and len(placed['overlapping']):
         #Placement has finished, but some edges are still unplaced
         raise Exception('One or more faces could not be placed without overlap!')
Beispiel #11
0
def maleFemaleFingerJointDecorationDrawing(length, width, male=True):
    """
    :param length: the length of edge to add finger joint;
    :param width: the width of finger joint;
    :return: return coordinates of finger joint decoration;
    """
    widthOfFingerForD = 5.0  ## the width of finger. ##
    extraSpaceOfFingerJointForD = 0.0
    compensationForAssembly = 0.5
    spaceOfEdgeForD = 20.0  ## the space left to avoid overlapping in corner, such as cube. ##
    upperLimitOfMD = eval_equation(length) / (
        2.0 * widthOfFingerForD
    ) - 2.5  ## the upper boundary for the number of fingers. ##
    length = eval_equation(length)
    width = eval_equation(width)

    ## calculate the coordinates of finger joint face. ##
    if length < eval_equation(spaceOfEdgeForD + widthOfFingerForD * 3.0):
        return "This edge is too short to add finger joint."
    else:
        nOfmFinger = int(eval_equation(
            upperLimitOfMD))  ## Find out how many fingers we need.##
        # print (nOfmFinger)

        if male:  ##maleFinger
            nOfOFinger = nOfmFinger
            adjustment = compensationForAssembly
            ## nOfOFinger is the number of opposite finger joint. it is the same as finger joints. ##
        else:
            nOfOFinger = nOfmFinger + 1
            adjustment = -compensationForAssembly
        ## maleFingerDecoration, the number of female fingers must bigger than male by 1. This is the rule. ##
        ## the module here is slightly different from finger joint ##
        fingerModule_rb = (
            (length / 2.0 + widthOfFingerForD * nOfOFinger -
             widthOfFingerForD / 2.0) + adjustment, extraSpaceOfFingerJointForD
        )  ## rb is right and bottom. ##
        fingerModule_rt = (
            (length / 2.0 + widthOfFingerForD * nOfOFinger -
             widthOfFingerForD / 2.0) + adjustment,
            width + extraSpaceOfFingerJointForD)  ## right and top##
        fingerModule_lt = (
            (length / 2.0 + widthOfFingerForD *
             (nOfOFinger - 1.0) - widthOfFingerForD / 2.0) - adjustment,
            width + extraSpaceOfFingerJointForD)  ## lt is left and top. ##
        fingerModule_lb = (
            (length / 2.0 + widthOfFingerForD *
             (nOfOFinger - 1.0) - widthOfFingerForD / 2.0) - adjustment,
            extraSpaceOfFingerJointForD)  ## left and bottom.##
        ## the order should be shown as following.  ##
        fingerDecorationModule = (fingerModule_rt, fingerModule_rb,
                                  fingerModule_lb, fingerModule_lt)
        ## define the coordinates of rest points except the fingers. ##
        # coordinatesOfFingerJoint = ((length, 0), (length, width))
        coordinatesOfFingerDecoration = ((0,
                                          width + extraSpaceOfFingerJointForD),
                                         (0, 0), (length, 0),
                                         (length,
                                          width + extraSpaceOfFingerJointForD))
        coordinatesOfFingerSeriesDecoration = (
        )  ## to save the coordinates of points of fingers. ##

        ## generate coordinates for fingers with a for loop.##
        if nOfOFinger == 1:
            coordinatesOfFingerSeriesDecoration = fingerDecorationModule
        else:
            listOfDFingerModule = [
                list(x) for x in fingerDecorationModule
            ]  ## convert the nested tuple into nested list because tuple is immutable. ##
        for i in range(nOfOFinger):
            if i == 0:  ## when i = 0, just append the tuple. ##
                coordinatesOfFingerSeriesDecoration += fingerDecorationModule
            else:  ## subtract 10 every time
                for j in range(len(listOfDFingerModule)):
                    listOfDFingerModule[j][
                        0] = listOfDFingerModule[j][0] - 2 * widthOfFingerForD
                tupleOfFingerModule = tuple(
                    tuple(li) for li in listOfDFingerModule
                )  ##convert the nested list into nested tuple. ##
                coordinatesOfFingerSeriesDecoration += tupleOfFingerModule
        return coordinatesOfFingerDecoration + coordinatesOfFingerSeriesDecoration
Beispiel #12
0
def maleFemaleFingerJointDecoration(face,
                                    faceEdge,
                                    thick,
                                    widget,
                                    male=True,
                                    **kwargs):
    """
    help to find how many fingers we need for different subcomponent.And add these fingers into the face.
    :param face: The face we add decoration;
    :param faceEdge: the edge we refer to;
    :param thick: the width of finger, it usually is 3.0mm.
    :param male: the type of decoration;
    :param widget: a face object to represent the finger;
    :param kwargs: kwargs;
    :return: None. the decoration will be added into selected face after operation
    """
    coords = face.edge_coords(face.edge_index(faceEdge))
    globalOrigin = coords[0]
    theta = arctan2(coords[1][1] - coords[0][1], coords[1][0] - coords[0][0])
    length = norm((coords[1][1] - coords[0][1], coords[1][0] - coords[0][0]))
    try:
        component = kwargs['component']
        length = float(eval_equation(length))
    except:
        # not sympy
        pass

    t = widget(length=length, width=thick, male=male)

    try:
        if kwargs["mirror"]:
            t.mirrorY()
            t.transform(origin=(0, thick / 2.0))
    except:
        pass

    ## find the number of fingers and create unwanted edges' index.
    widthOfFingerForD = 5.0  ## the width of finger. ##
    upperLimitOfMD = eval_equation(length) / (2.0 * widthOfFingerForD) - 2.5
    nOfmFinger = int(eval_equation(upperLimitOfMD))
    if male:  ##maleFinger
        nOfOFinger = nOfmFinger
    else:
        nOfOFinger = nOfmFinger + 1
    unWantedIndex = range(2, 3 + nOfOFinger * 4, 4)  ## 2, 6, 10, 14 and so on.
    unWantedIndex.append(1)
    unWantedIndex.append(3)
    unWantedEdgeNames = ["e%d" % i for i in unWantedIndex]

    ## add all of the edges into the face we select ##
    for (name, edge) in t.edges.iteritems():
        e = edge.copy()
        e.transform(angle=theta, origin=globalOrigin)
        if name in unWantedEdgeNames:  ## ignore all the bottom edge. ##
            continue
        face.add_decoration(
            (((e.x1, e.y1), (e.x2, e.y2)), e.edge_type.edge_type))
    try:
        if kwargs["alternating"]:
            t.mirrorY()
            t.transform(origin=(0, thick))
    except:
        pass