The HashCode designed in arc between two nodes of AAG

jianbaoxia

CAD master
I note there are Hashcode function in "asiAlgo_AAG.h" The code:
Code:
  //! Arc between two nodes of AAG. The arc is the explicit representation
  //! for adjacency relation.
  struct t_arc
  {
    t_topoId F1; //!< First face.
    t_topoId F2; //!< Second face.

    //! ctor default.
    t_arc() : F1(0), F2(0) {}

    //! ctor with parameters.
    t_arc(const t_topoId _F1, const t_topoId _F2) : F1(_F1), F2(_F2) {}

    //! \return hash code for the arc.
    static int HashCode(const t_arc& arc, const int upper)
    {
      int key = arc.F1 + arc.F2;
      key += (key << 10);
      key ^= (key >> 6);
      key += (key << 3);
      key ^= (key >> 11);
      return (key & 0x7fffffff) % upper;
    }

    //! \return true if two links are equal.
    static int IsEqual(const t_arc& arc1, const t_arc& arc2)
    {
      return ( (arc1.F1 == arc2.F1) && (arc1.F2 == arc2.F2) ) ||
             ( (arc1.F2 == arc2.F1) && (arc1.F1 == arc2.F2) );
    }
  };

I'm curious, why the HashCode design like this, I never use write hashcode by myself before, I was learn it in data structure book.
Is the design has some relations with the "TColStd_PackedMapOfInteger", which was used in AAG.

Actually, after read Anatomy of CAD feature and code in "asiAlgo_AAG::init()" I still have no idea what's the usage of TColStd_PackedMapOfInteger.
 

Quaoar

Administrator
Staff member
This is a hash function for a pair of two integers where their order does not matter. I've been using this code for ages and initially took it from someone else's project, so cannot say if it's good or bad. It just works. Why are you asking? Does it look weird?

As for TColStd_PackedMapOfInteger, you do not need to understand its anatomy to use feature recognition. Just bear in mind that it's an unordered map of integers that exposes a Boolean set logic API. The article you mentioned reveals some details of its implementation and is mostly useful for checking the map's contents in debug sessions.

Btw, this map is typedefed as asiAlgo_Feature in analysis situs.
 

jianbaoxia

CAD master
@Quaoar Just out of curiosity,I try get AAG from step file with the help of "TopExp::MapShapes" and "TopExp::MapShapesAndAncestors". Then try to calculate the dihedral angle for convexity. Your work on "asiAlgo_AAG" is much power, actually I had do some work to get AAG from step file matedata, but is simple. With the tool of OCCT, it can be easier to achieve some thing, It's nice.
 
Last edited:

Quaoar

Administrator
Staff member
AAG in Analysis Situs is quite a complex piece indeed. You may want just to keep the adjacency matrix, vexity attributes and eliminate everything that's not necessary. But the one in Analysis Situs is well profiled and was used in many projects, including some commercial ones, so it should be reliable enough.
 

jianbaoxia

CAD master
@Quaoar You are right, AAG in Analysis Situs is powerful and complex. Thanks to you blog, I can try to extract vexity attributes in simple code, I have work for it a few days, forgive me for inefficiency T_T。I was almost finished the AAG yesterday, however, I make some mistakes in get the adjacency face, I get there map of my stepfile:
Code:
    TopTools_IndexedMapOfShape m_faces; // store all the face
    TopTools_IndexedMapOfShape m_edges; // store all the edge
    TopTools_IndexedDataMapOfShapeListOfShape m_edgesFaces; // 

    // 
    TopExp::MapShapes(partShape, TopAbs_FACE, m_faces);
    TopExp::MapShapes(partShape, TopAbs_EDGE, m_edges);
    TopExp::MapShapesAndAncestors(partShape, TopAbs_EDGE, TopAbs_FACE, m_edgesFaces);

I try to get the adjacency face base the three maps, it has some challenges for me, I'm working for it, hope I can succeed.
 

jianbaoxia

CAD master
@Quaoar I solve it out; OCCT has powerful TopoTool; however, I was in troubled a day, then found this tool on hand. I feel weak for my own stupidity. T_T There are my code to get adjacency faces:
Code:
    TopTools_IndexedMapOfShape m_faces; // store all the face
    TopTools_IndexedMapOfShape m_edges; // store all the edge
    TopTools_IndexedDataMapOfShapeListOfShape m_edgesFaces; // 

    // 
    TopExp::MapShapes(partShape, TopAbs_FACE, m_faces);
    TopExp::MapShapes(partShape, TopAbs_EDGE, m_edges);
    TopExp::MapShapesAndAncestors(partShape, TopAbs_EDGE, TopAbs_FACE, m_edgesFaces);
Code:
    std::map<int, std::set<int>> adFaceMap; // store adjacency faces
    for (TopExp_Explorer exp_face(partShape, TopAbs_FACE); exp_face.More(); exp_face.Next()) 
    {
        const int& face_idex = m_faces.FindIndex( TopoDS::Face(exp_face.Current()) );
        std::set<int> link_face_list; // store adjacency faces of the current face
        // 
        for (TopExp_Explorer exp_edge(exp_face.Current(), TopAbs_EDGE); exp_edge.More(); exp_edge.Next())
        {
            const TopoDS_Edge& edge_current = TopoDS::Edge(exp_edge.Current());
            const TopTools_ListOfShape& adjacentFaces = m_edgesFaces.FindFromKey(edge_current); // 与该 edge 相邻的 face
            
            for (TopTools_ListIteratorOfListOfShape facelist(adjacentFaces); facelist.More(); facelist.Next())
            {
                const int link_face_idx = m_faces.FindIndex(facelist.Value());
                if (face_idex == link_face_idx) // skip for itself
                    continue;
                if (link_face_list.count(link_face_idx) > 0) // skip repeat face
                    continue;
                link_face_list.insert(link_face_idx);
            }
        }

        adFaceMap.insert(std::pair<int, std::set<int>>(face_idex, link_face_list));
    }

The code can get the oriented graph, but I would like to get unoriented graph, it still have work for me.
 
Top