Salome HOME
2.3.3.2 Point creation by projection of another point on a plane
authordbv <dbv@opencascade.com>
Tue, 26 Jun 2018 18:34:29 +0000 (21:34 +0300)
committerdbv <dbv@opencascade.com>
Wed, 27 Jun 2018 12:57:35 +0000 (15:57 +0300)
13 files changed:
src/ConstructionAPI/ConstructionAPI_Point.cpp
src/ConstructionAPI/ConstructionAPI_Point.h
src/ConstructionPlugin/CMakeLists.txt
src/ConstructionPlugin/ConstructionPlugin_Point.cpp
src/ConstructionPlugin/ConstructionPlugin_Point.h
src/ConstructionPlugin/Test/TestPoint_ProjectOnFace.py [new file with mode: 0644]
src/ConstructionPlugin/icons/point_by_projection_32x32.png [deleted file]
src/ConstructionPlugin/icons/point_by_projection_on_face_32x32.png [new file with mode: 0644]
src/ConstructionPlugin/icons/point_by_projection_on_line_32x32.png [new file with mode: 0644]
src/ConstructionPlugin/point_widget.xml
src/GeomAlgoAPI/GeomAlgoAPI_PointBuilder.cpp
src/GeomAlgoAPI/GeomAlgoAPI_PointBuilder.h
src/ModelHighAPI/ModelHighAPI_Macro.h

index 8d045791f3404bb4e4032f16246322e8e93dc3cf..ca427fe7de5930e12a5b2c886d5afd58384d0180 100644 (file)
@@ -67,14 +67,13 @@ ConstructionAPI_Point::ConstructionAPI_Point(const std::shared_ptr<ModelAPI_Feat
   if(initialize()) {
     GeomAPI_Shape::ShapeType aType1 = getShapeType(theObject1);
     GeomAPI_Shape::ShapeType aType2 = getShapeType(theObject2);
-    /*
     if(aType1 == GeomAPI_Shape::VERTEX && aType2 == GeomAPI_Shape::FACE) {
       // If first object is vertex and second object is face then set by projection.
-      setByProjection(theObject1, theObject2);
-    } else if(aType1 == GeomAPI_Shape::EDGE && aType2 == GeomAPI_Shape::EDGE) {
+      setByProjectionOnFace(theObject1, theObject2);
+    } /*else if(aType1 == GeomAPI_Shape::EDGE && aType2 == GeomAPI_Shape::EDGE) {
       // If both objects are edges then set by lines intersection.
       setByLinesIntersection(theObject1, theObject2);
-    } else */if(aType1 == GeomAPI_Shape::EDGE && aType2 == GeomAPI_Shape::FACE) {
+    } */ else if(aType1 == GeomAPI_Shape::EDGE && aType2 == GeomAPI_Shape::FACE) {
       // If first object is edge and second object is face then set by line and plane intersection.
       setByLineAndPlaneIntersection(theObject1, theObject2);
     }
@@ -122,18 +121,19 @@ void ConstructionAPI_Point::setByOffsetOnEdge(const ModelHighAPI_Selection& theE
   execute();
 }
 
-/*
 //==================================================================================================
-void ConstructionAPI_Point::setByProjection(const ModelHighAPI_Selection& theVertex,
-                                            const ModelHighAPI_Selection& theFace)
+void ConstructionAPI_Point::setByProjectionOnFace(const ModelHighAPI_Selection& theVertex,
+                                                  const ModelHighAPI_Selection& theFace)
 {
-  fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_PROJECTION(), mycreationMethod);
-  fillAttribute(theVertex, mypoint);
-  fillAttribute(theFace, myplane);
+  fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_PROJECTION_ON_FACE(),
+                mycreationMethod);
+  fillAttribute(theVertex, mypoinToProjectOnFace);
+  fillAttribute(theFace, myfaceForPointProjection);
 
   execute();
 }
 
+/*
 //==================================================================================================
 void ConstructionAPI_Point::setByLinesIntersection(const ModelHighAPI_Selection& theEdge1,
                                                    const ModelHighAPI_Selection& theEdge2)
@@ -170,15 +170,13 @@ void ConstructionAPI_Point::dump(ModelHighAPI_Dumper& theDumper) const
 
   if (aMeth == "" || // default is XYZ
       aMeth == ConstructionPlugin_Point::CREATION_METHOD_BY_XYZ()) {
-    theDumper << x() << ", " << y() << ", " << z() << ")" << std::endl;
+    theDumper << x() << ", " << y() << ", " << z();
   } else if (aMeth == ConstructionPlugin_Point::CREATION_METHOD_BY_LINE_AND_PLANE_INTERSECTION()) {
     theDumper << intersectionLine() << ", " <<intersectionPlane() ;
     if (!useOffset()->value().empty()) { // call method with defined offset
       theDumper << ", " << offset() << ", " << reverseOffset();
     }
-    theDumper << ")" << std::endl;
-  }
-  else if (aMeth == ConstructionPlugin_Point::CREATION_METHOD_BY_DISTANCE_ON_EDGE()) {
+  } else if (aMeth == ConstructionPlugin_Point::CREATION_METHOD_BY_DISTANCE_ON_EDGE()) {
     theDumper << edge() << ", ";
     if (offsetType()->value() == ConstructionPlugin_Point::OFFSET_TYPE_BY_DISTANCE()) {
       theDumper << distance() << ", " << false;
@@ -186,8 +184,12 @@ void ConstructionAPI_Point::dump(ModelHighAPI_Dumper& theDumper) const
     else {
       theDumper << ratio() << ", " << true;
     }
-    theDumper << ", " << reverse()->value() << ")" << std::endl;
+    theDumper << ", " << reverse()->value();
+  } else if (aMeth == ConstructionPlugin_Point::CREATION_METHOD_BY_PROJECTION_ON_FACE()) {
+    theDumper << mypoinToProjectOnFace << ", " << myfaceForPointProjection;
   }
+
+  theDumper << ")" << std::endl;
 }
 
 //==================================================================================================
index 087ea95e84711a92dfd6f0e4dc55ab1de6790879..7e412a2f499a78ea2fd0f57fe0df931f63ae8d90 100644 (file)
@@ -67,7 +67,7 @@ public:
   CONSTRUCTIONAPI_EXPORT
   virtual ~ConstructionAPI_Point();
 
-  INTERFACE_14(ConstructionPlugin_Point::ID(),
+  INTERFACE_16(ConstructionPlugin_Point::ID(),
                x, ConstructionPlugin_Point::X(), ModelAPI_AttributeDouble, /** X attribute */,
                y, ConstructionPlugin_Point::Y(), ModelAPI_AttributeDouble, /** Y attribute */,
                z, ConstructionPlugin_Point::Z(), ModelAPI_AttributeDouble, /** Z attribute */,
@@ -92,7 +92,11 @@ public:
                ratio, ConstructionPlugin_Point::RATIO(),
                ModelAPI_AttributeDouble, /** Ratio */,
                reverse, ConstructionPlugin_Point::REVERSE(),
-               ModelAPI_AttributeBoolean, /** Reverse */)
+               ModelAPI_AttributeBoolean, /** Reverse */,
+               poinToProjectOnFace, ConstructionPlugin_Point::POINT_TO_PROJECT_ON_FACE(),
+               ModelAPI_AttributeSelection, /** Point to project on face */,
+               faceForPointProjection, ConstructionPlugin_Point::FACE_FOR_POINT_PROJECTION(),
+               ModelAPI_AttributeSelection, /** Face for point projection */)
 
 
   /// Set point values.
@@ -108,17 +112,18 @@ public:
                          const bool theUseRatio = false,
                          const bool theReverse = false);
 
-  /*
   /// Set point and plane for projection.
   CONSTRUCTIONAPI_EXPORT
-  void setByProjection(const ModelHighAPI_Selection& theVertex,
-                       const ModelHighAPI_Selection& theFace);
+  void setByProjectionOnFace(const ModelHighAPI_Selection& theVertex,
+                             const ModelHighAPI_Selection& theFace);
 
+  /*
   /// Set lines for intersections.
   CONSTRUCTIONAPI_EXPORT
   void setByLinesIntersection(const ModelHighAPI_Selection& theEdge1,
                               const ModelHighAPI_Selection& theEdge2);
   */
+
   /// Set line and plane for intersections.
   CONSTRUCTIONAPI_EXPORT
   void setByLineAndPlaneIntersection(const ModelHighAPI_Selection& theEdge,
index 11cfdcedc106841b05ff604f13b72495b2f99f2a..f374cc0e6c9961951dc1b8c2330dd30266572678 100644 (file)
@@ -80,5 +80,6 @@ ADD_UNIT_TESTS(TestAxisCreation.py
                TestPoint_XYZ.py
                TestPoint_LineAndPlane.py
                TestPoint_Edge.py
+               TestPoint_ProjectOnFace.py
                TestPointName.py
                TestPlane.py)
index 2081f4ed12a3ca764a9bb6f7f2b9f1c4dae33168..ee86684379ef1b211db52a43548f1d2fe6a3c293 100644 (file)
@@ -56,9 +56,6 @@ void ConstructionPlugin_Point::initAttributes()
   data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
 
 /*
-  data()->addAttribute(POINT(), ModelAPI_AttributeSelection::typeId());
-  data()->addAttribute(PLANE(), ModelAPI_AttributeSelection::typeId());
-
   data()->addAttribute(FIRST_LINE(), ModelAPI_AttributeSelection::typeId());
   data()->addAttribute(SECOND_LINE(), ModelAPI_AttributeSelection::typeId());
 */
@@ -75,6 +72,9 @@ void ConstructionPlugin_Point::initAttributes()
   data()->addAttribute(DISTANCE(), ModelAPI_AttributeDouble::typeId());
   data()->addAttribute(RATIO(), ModelAPI_AttributeDouble::typeId());
   data()->addAttribute(REVERSE(), ModelAPI_AttributeBoolean::typeId());
+
+  data()->addAttribute(POINT_TO_PROJECT_ON_FACE(), ModelAPI_AttributeSelection::typeId());
+  data()->addAttribute(FACE_FOR_POINT_PROJECTION(), ModelAPI_AttributeSelection::typeId());
 }
 
 //==================================================================================================
@@ -90,11 +90,11 @@ void ConstructionPlugin_Point::execute()
     aShape = createByXYZ();
   } else if(aCreationMethod == CREATION_METHOD_BY_DISTANCE_ON_EDGE()) {
     aShape = createByDistanceOnEdge();
-  }/* else if(aCreationMethod == CREATION_METHOD_BY_PROJECTION()) {
-    aShape = createByProjection();
-  } else if(aCreationMethod == CREATION_METHOD_BY_LINES_INTERSECTION()) {
+  } else if(aCreationMethod == CREATION_METHOD_BY_PROJECTION_ON_FACE()) {
+    aShape = createByProjectionOnFace();
+  } /* else if(aCreationMethod == CREATION_METHOD_BY_LINES_INTERSECTION()) {
     aShape = createByLinesIntersection();
-  }*/ else if(aCreationMethod == CREATION_METHOD_BY_LINE_AND_PLANE_INTERSECTION()) {
+  } */ else if(aCreationMethod == CREATION_METHOD_BY_LINE_AND_PLANE_INTERSECTION()) {
     // this may produce several points
     std::list<std::shared_ptr<GeomAPI_Vertex> > aPoints = createByLineAndPlaneIntersection();
     if (!aPoints.empty()) { // if no points found produce the standard error later
@@ -168,12 +168,12 @@ std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByDistanceOnEdge
 
   return GeomAlgoAPI_PointBuilder::vertexOnEdge(anEdge, aValue, anIsPercent, anIsReverse);
 }
-/*
+
 //==================================================================================================
-std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByProjection()
+std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByProjectionOnFace()
 {
   // Get point.
-  AttributeSelectionPtr aPointSelection = selection(POINT());
+  AttributeSelectionPtr aPointSelection = selection(POINT_TO_PROJECT_ON_FACE());
   GeomShapePtr aPointShape = aPointSelection->value();
   if(!aPointShape.get()) {
     aPointShape = aPointSelection->context()->shape();
@@ -181,7 +181,7 @@ std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByProjection()
   std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aPointShape));
 
   // Get plane.
-  AttributeSelectionPtr aPlaneSelection = selection(PLANE());
+  AttributeSelectionPtr aPlaneSelection = selection(FACE_FOR_POINT_PROJECTION());
   GeomShapePtr aPlaneShape = aPlaneSelection->value();
   if(!aPlaneShape.get()) {
     aPlaneShape = aPlaneSelection->context()->shape();
@@ -191,6 +191,7 @@ std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByProjection()
   return GeomAlgoAPI_PointBuilder::vertexByProjection(aVertex, aFace);
 }
 
+/*
 //==================================================================================================
 std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByLinesIntersection()
 {
index 7537970a86564e671d0b94c9cabef0e26611d266..a5f84a6d39db0d33217a8a8059f8d3dcf72c840a 100644 (file)
@@ -68,14 +68,14 @@ public:
     return MY_CREATION_METHOD_ID;
   }
 
-  /*
   /// Attribute name for creation method.
-  inline static const std::string& CREATION_METHOD_BY_PROJECTION()
+  inline static const std::string& CREATION_METHOD_BY_PROJECTION_ON_FACE()
   {
-    static const std::string MY_CREATION_METHOD_ID("by_projection");
+    static const std::string MY_CREATION_METHOD_ID("by_projection_on_face");
     return MY_CREATION_METHOD_ID;
   }
 
+  /*
   /// Attribute name for creation method.
   inline static const std::string& CREATION_METHOD_BY_LINES_INTERSECTION()
   {
@@ -161,21 +161,21 @@ public:
     return ATTR_ID;
   }
 
-  /*
-  /// Attribute name for point.
-  inline static const std::string& POINT()
+  /// Attribute name for point to project on surface.
+  inline static const std::string& POINT_TO_PROJECT_ON_FACE()
   {
-    static const std::string ATTR_ID("point");
+    static const std::string ATTR_ID("point_to_project_on_face");
     return ATTR_ID;
   }
 
-  /// Attribute name for plane.
-  inline static const std::string& PLANE()
+  /// Attribute name for face for point projection.
+  inline static const std::string& FACE_FOR_POINT_PROJECTION()
   {
-    static const std::string ATTR_ID("plane");
+    static const std::string ATTR_ID("face_for_point_projection");
     return ATTR_ID;
   }
 
+  /*
   /// Attribute name for selected first line.
   inline static const std::string& FIRST_LINE()
   {
@@ -245,8 +245,8 @@ public:
 private:
   std::shared_ptr<GeomAPI_Vertex> createByXYZ();
   std::shared_ptr<GeomAPI_Vertex> createByDistanceOnEdge();
-  /*std::shared_ptr<GeomAPI_Vertex> createByProjection();
-  std::shared_ptr<GeomAPI_Vertex> createByLinesIntersection();*/
+  std::shared_ptr<GeomAPI_Vertex> createByProjectionOnFace();
+  /*std::shared_ptr<GeomAPI_Vertex> createByLinesIntersection();*/
   std::list<std::shared_ptr<GeomAPI_Vertex> > createByLineAndPlaneIntersection();
 
 };
diff --git a/src/ConstructionPlugin/Test/TestPoint_ProjectOnFace.py b/src/ConstructionPlugin/Test/TestPoint_ProjectOnFace.py
new file mode 100644 (file)
index 0000000..1b5218e
--- /dev/null
@@ -0,0 +1,49 @@
+## Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+"""
+Test case for Construction Point feature by projection point on face.
+"""
+
+from salome.shaper import model
+from GeomAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
+SketchPoint_1 = Sketch_1.addPoint(50, 50)
+model.do()
+Box_1 = model.addBox(Part_1_doc, 10, 100, 100)
+Point_2 = model.addPoint(Part_1_doc, model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_1"), model.selection("FACE", "Box_1_1/Front"))
+Point_3 = model.addPoint(Part_1_doc, model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_1"), model.selection("FACE", "PartSet/XOY"))
+model.do()
+model.end()
+
+assert (len(Point_2.results()) > 0)
+rightPosition = GeomAPI_Vertex(10, 0, 50)
+assert(rightPosition.isEqual(Point_2.results()[0].resultSubShapePair()[0].shape()))
+
+assert (len(Point_3.results()) > 0)
+rightPosition = GeomAPI_Vertex(50, 0, 0)
+assert(rightPosition.isEqual(Point_3.results()[0].resultSubShapePair()[0].shape()))
+
+assert(model.checkPythonDump())
diff --git a/src/ConstructionPlugin/icons/point_by_projection_32x32.png b/src/ConstructionPlugin/icons/point_by_projection_32x32.png
deleted file mode 100644 (file)
index 91900fe..0000000
Binary files a/src/ConstructionPlugin/icons/point_by_projection_32x32.png and /dev/null differ
diff --git a/src/ConstructionPlugin/icons/point_by_projection_on_face_32x32.png b/src/ConstructionPlugin/icons/point_by_projection_on_face_32x32.png
new file mode 100644 (file)
index 0000000..91900fe
Binary files /dev/null and b/src/ConstructionPlugin/icons/point_by_projection_on_face_32x32.png differ
diff --git a/src/ConstructionPlugin/icons/point_by_projection_on_line_32x32.png b/src/ConstructionPlugin/icons/point_by_projection_on_line_32x32.png
new file mode 100644 (file)
index 0000000..187864f
Binary files /dev/null and b/src/ConstructionPlugin/icons/point_by_projection_on_line_32x32.png differ
index 63fd48350fb56e8feccaf5cdc2526895ceb75c21..5db2d6657a2fab3a7b33395f0c0f0905651ed9df 100644 (file)
@@ -82,25 +82,25 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
            tooltip="Distance from edge end point."
            default="false"/>
     </box>
-<!--
-    <box id="by_projection"
-         title="By projection"
+    <box id="by_projection_on_face"
+         title="By projection on face"
          tooltip="Point on face surface by projection selected point."
-         icon="icons/Construction/point_by_projection_32x32.png">
-      <shape_selector id="point"
+         icon="icons/Construction/point_by_projection_on_face_32x32.png">
+      <shape_selector id="point_to_project_on_face"
                       label="Point"
                       tooltip="Point for projection."
                       icon="icons/Construction/point.png"
                       shape_types="vertex">
       </shape_selector>
-      <shape_selector id="plane"
-                      label="Plane"
-                      tooltip="Plane for projection."
+      <shape_selector id="face_for_point_projection"
+                      label="face"
+                      tooltip="Face for projection."
                       icon="icons/Construction/face.png"
                       shape_types="face">
         <validator id="GeomValidators_Face" parameters="plane"/>
       </shape_selector>
     </box>
+<!--
     <box id="by_lines_intersection"
          title="By two lines intersection"
          tooltip="Point by intersection of two coplanar lines."
index 19796f0a2be92a843e839c3f66d4300f6ac81746..c46bfd364bb27658b4856932e950d389cd2fa042 100644 (file)
@@ -125,16 +125,16 @@ std::shared_ptr<GeomAPI_Vertex> GeomAlgoAPI_PointBuilder::vertexOnEdge(
 //==================================================================================================
 std::shared_ptr<GeomAPI_Vertex> GeomAlgoAPI_PointBuilder::vertexByProjection(
     const std::shared_ptr<GeomAPI_Vertex> theVertex,
-    const std::shared_ptr<GeomAPI_Face> thePlane)
+    const std::shared_ptr<GeomAPI_Face> theFace)
 {
   std::shared_ptr<GeomAPI_Vertex> aVertex;
 
-  if(!theVertex.get() || !thePlane.get() || !thePlane->isPlanar()) {
+  if(!theVertex.get() || !theFace.get() || !theFace->isPlanar()) {
     return aVertex;
   }
 
   std::shared_ptr<GeomAPI_Pnt> aProjPnt = theVertex->point();
-  std::shared_ptr<GeomAPI_Pln> aProjPln = thePlane->getPlane();
+  std::shared_ptr<GeomAPI_Pln> aProjPln = theFace->getPlane();
 
   std::shared_ptr<GeomAPI_Pnt> aPnt = aProjPln->project(aProjPnt);
 
index 50e478752be06c4bc527332569d746fc6ab0496b..2d59a12636d183c2cc62c8154ea929e0734a53c9 100644 (file)
@@ -58,11 +58,11 @@ public:
 
   /// \brief Creates vertex by projection another vertex on plane.
   /// \param[in] theVertex vertex to project.
-  /// \param[in] thePlane face for projection. Should be planar.
+  /// \param[in] theFace face for projection. Should be planar.
   /// \return created vertex.
   static std::shared_ptr<GeomAPI_Vertex>
     vertexByProjection(const std::shared_ptr<GeomAPI_Vertex> theVertex,
-                       const std::shared_ptr<GeomAPI_Face> thePlane);
+                       const std::shared_ptr<GeomAPI_Face> theFace);
 
   /// \brief Creates vertex by intersection two coplanar lines.
   /// \param[in] theEdge1 first linear edge.
index 4b55ce8b835a27faa478444502f540bd470a41d8..40417def5f1d61fea68cc3ca00c4f8d6ee10f91e 100644 (file)
     END_INIT() \
   public:
 
+//--------------------------------------------------------------------------------------
+#define INTERFACE_16(KIND, \
+                     N_0, AN_0, T_0, C_0, \
+                     N_1, AN_1, T_1, C_1, \
+                     N_2, AN_2, T_2, C_2, \
+                     N_3, AN_3, T_3, C_3, \
+                     N_4, AN_4, T_4, C_4, \
+                     N_5, AN_5, T_5, C_5, \
+                     N_6, AN_6, T_6, C_6, \
+                     N_7, AN_7, T_7, C_7, \
+                     N_8, AN_8, T_8, C_8, \
+                     N_9, AN_9, T_9, C_9, \
+                     N_10, AN_10, T_10, C_10, \
+                     N_11, AN_11, T_11, C_11, \
+                     N_12, AN_12, T_12, C_12, \
+                     N_13, AN_13, T_13, C_13, \
+                     N_14, AN_14, T_14, C_14, \
+                     N_15, AN_15, T_15, C_15) \
+  public: \
+    INTERFACE_COMMON(KIND) \
+    DEFINE_ATTRIBUTE(N_0, T_0, C_0) \
+    DEFINE_ATTRIBUTE(N_1, T_1, C_1) \
+    DEFINE_ATTRIBUTE(N_2, T_2, C_2) \
+    DEFINE_ATTRIBUTE(N_3, T_3, C_3) \
+    DEFINE_ATTRIBUTE(N_4, T_4, C_4) \
+    DEFINE_ATTRIBUTE(N_5, T_5, C_5) \
+    DEFINE_ATTRIBUTE(N_6, T_6, C_6) \
+    DEFINE_ATTRIBUTE(N_7, T_7, C_7) \
+    DEFINE_ATTRIBUTE(N_8, T_8, C_8) \
+    DEFINE_ATTRIBUTE(N_9, T_9, C_9) \
+    DEFINE_ATTRIBUTE(N_10, T_10, C_10) \
+    DEFINE_ATTRIBUTE(N_11, T_11, C_11) \
+    DEFINE_ATTRIBUTE(N_12, T_12, C_12) \
+    DEFINE_ATTRIBUTE(N_13, T_13, C_13) \
+    DEFINE_ATTRIBUTE(N_14, T_14, C_14) \
+    DEFINE_ATTRIBUTE(N_15, T_15, C_15) \
+  protected: \
+    START_INIT() \
+      SET_ATTRIBUTE(N_0, T_0, AN_0) \
+      SET_ATTRIBUTE(N_1, T_1, AN_1) \
+      SET_ATTRIBUTE(N_2, T_2, AN_2) \
+      SET_ATTRIBUTE(N_3, T_3, AN_3) \
+      SET_ATTRIBUTE(N_4, T_4, AN_4) \
+      SET_ATTRIBUTE(N_5, T_5, AN_5) \
+      SET_ATTRIBUTE(N_6, T_6, AN_6) \
+      SET_ATTRIBUTE(N_7, T_7, AN_7) \
+      SET_ATTRIBUTE(N_8, T_8, AN_8) \
+      SET_ATTRIBUTE(N_9, T_9, AN_9) \
+      SET_ATTRIBUTE(N_10, T_10, AN_10) \
+      SET_ATTRIBUTE(N_11, T_11, AN_11) \
+      SET_ATTRIBUTE(N_12, T_12, AN_12) \
+      SET_ATTRIBUTE(N_13, T_13, AN_13) \
+      SET_ATTRIBUTE(N_14, T_14, AN_14) \
+      SET_ATTRIBUTE(N_15, T_15, AN_15) \
+    END_INIT() \
+  public:
+
 //--------------------------------------------------------------------------------------
 #define INTERFACE_20(KIND, \
                      N_0, AN_0, T_0, C_0, \