diff --git a/documentation/examples/scripts/diagonals.py b/documentation/examples/scripts/diagonals.py
new file mode 100644
index 00000000..9c2311c3
--- /dev/null
+++ b/documentation/examples/scripts/diagonals.py
@@ -0,0 +1,90 @@
+#!/usr/bin/python
+
+import sys
+from Hurricane import *
+from CRL import *
+
+
+def toDbU ( l ): return DbU.fromLambda(l)
+
+
+def doBreak ( level, message ):
+ UpdateSession.close()
+ Breakpoint.stop( level, message )
+ UpdateSession.open()
+
+
+def buildDiagonals ( editor ):
+ DbU.setPolygonStep( toDbU(1.0) )
+
+ UpdateSession.open()
+
+ cell = AllianceFramework.get().createCell( 'diagonal' )
+ cell.setTerminal( True )
+
+ cell.setAbutmentBox( Box( toDbU(-5.0), toDbU(-5.0), toDbU(65.0), toDbU(75.0) ) )
+
+ if editor:
+ UpdateSession.close()
+ editor.setCell( cell )
+ editor.fit()
+ UpdateSession.open()
+
+ technology = DataBase.getDB().getTechnology()
+ metal1 = technology.getLayer( "metal1" )
+ metal2 = technology.getLayer( "metal2" )
+ metal4 = technology.getLayer( "metal4" )
+ poly = technology.getLayer( "POLY" )
+ ptrans = technology.getLayer( "PTRANS" )
+ ntrans = technology.getLayer( "NTRANS" )
+ pdif = technology.getLayer( "PDIF" )
+ ndif = technology.getLayer( "NDIF" )
+ contdifn = technology.getLayer( "CONT_DIF_N" )
+ contdifp = technology.getLayer( "CONT_DIF_P" )
+ nwell = technology.getLayer( "NWELL" )
+ contpoly = technology.getLayer( "CONT_POLY" )
+ ntie = technology.getLayer( "NTIE" )
+
+
+ net = Net.create( cell, 'my_net' )
+ net.setExternal( True )
+
+ Diagonal.create( net, metal2
+ , Point( toDbU(20.0), toDbU(10.0) )
+ , Point( toDbU(10.0), toDbU(20.0) )
+ , toDbU(4.0)
+ )
+ Vertical.create( net, metal2, toDbU(10.0), toDbU(4.0), toDbU(20.0), toDbU(30.0) )
+ Diagonal.create( net, metal2
+ , Point( toDbU(10.0), toDbU(30.0) )
+ , Point( toDbU(20.0), toDbU(40.0) )
+ , toDbU(4.0)
+ )
+ Horizontal.create( net, metal2, toDbU(40.0), toDbU(4.0), toDbU(20.0), toDbU(30.0) )
+ Diagonal.create( net, metal2
+ , Point( toDbU(30.0), toDbU(40.0) )
+ , Point( toDbU(40.0), toDbU(30.0) )
+ , toDbU(4.0)
+ )
+ Vertical.create( net, metal2, toDbU(40.0), toDbU(4.0), toDbU(30.0), toDbU(20.0) )
+ Diagonal.create( net, metal2
+ , Point( toDbU(40.0), toDbU(20.0) )
+ , Point( toDbU(30.0), toDbU(10.0) )
+ , toDbU(4.0)
+ )
+ Horizontal.create( net, metal2, toDbU(10.0), toDbU(4.0), toDbU(30.0), toDbU(20.0) )
+
+ UpdateSession.close()
+
+ #AllianceFramework.get().saveCell( cell, Catalog.State.Views )
+ # No saving as we don't have a GDSII driver (yet).
+ return
+
+
+def ScriptMain ( **kw ):
+ editor = None
+ if kw.has_key('editor') and kw['editor']:
+ editor = kw['editor']
+
+ buildDiagonals( editor )
+ return True
diff --git a/hurricane/doc/hurricane/Diagonal.dox b/hurricane/doc/hurricane/Diagonal.dox
new file mode 100644
index 00000000..7c7ac59f
--- /dev/null
+++ b/hurricane/doc/hurricane/Diagonal.dox
@@ -0,0 +1,32 @@
+
+ // -*- C++ -*-
+
+
+ namespace Hurricane {
+
+ /*! \class Diagonal
+ * \brief Diagonal description (\b API)
+ *
+ * \section secDiagonalIntro Introduction
+ *
+ * Create 45° or 135° segments.
+ *
+ * The minimal step length for the manhattanisation is set up with
+ * DbU::setDiagonalStep().
+ */
+
+
+ /*! \typedef Diagonal::Super
+ * Useful for calling upon methods of the base class without
+ * knowing it.
+ */
+
+
+ /*! \function Diagonal* Diagonal::create( Net* net, const Layer* layer, const Point& source, const Point& target, DbU::Unit width );
+ * Create a diagonal segment of \c layer in \c net.
+ */
+
+ // \}
+
+
+ }
diff --git a/hurricane/doc/hurricane/Polygon.dox b/hurricane/doc/hurricane/Polygon.dox
index 58c692e1..06a823a9 100644
--- a/hurricane/doc/hurricane/Polygon.dox
+++ b/hurricane/doc/hurricane/Polygon.dox
@@ -7,7 +7,7 @@
/*! \class Polygon
* \brief Polygon description (\b API)
*
- * \section secPadIntro Introduction
+ * \section secPolygonIntro Introduction
*
* Polygon should be used to create huge convex and manhattanized polygons.
* Manhattanization is done so the real geometric shape is completly included
diff --git a/hurricane/doc/hurricane/doxyfile b/hurricane/doc/hurricane/doxyfile
index 5054775c..1b5eabe2 100644
--- a/hurricane/doc/hurricane/doxyfile
+++ b/hurricane/doc/hurricane/doxyfile
@@ -705,6 +705,8 @@ INPUT = Generalities.dox \
Pad.dox \
../../src/hurricane/hurricane/Polygon.h \
Polygon.dox \
+ ../../src/hurricane/hurricane/Diagonal.h \
+ Diagonal.dox \
../../src/hurricane/hurricane/Rubbers.h \
../../src/hurricane/hurricane/Rubber.h \
RoutingPad.dox \
diff --git a/hurricane/src/hurricane/CMakeLists.txt b/hurricane/src/hurricane/CMakeLists.txt
index b9c62711..b6c2e920 100644
--- a/hurricane/src/hurricane/CMakeLists.txt
+++ b/hurricane/src/hurricane/CMakeLists.txt
@@ -78,6 +78,7 @@
hurricane/Region.h
hurricane/Relation.h
hurricane/RoutingPad.h hurricane/RoutingPads.h
+ hurricane/Diagonal.h
hurricane/Rubber.h hurricane/Rubbers.h
hurricane/Segment.h hurricane/Segments.h
hurricane/Selectors.h
@@ -161,6 +162,7 @@
Horizontal.cpp
Pad.cpp
RoutingPad.cpp
+ Diagonal.cpp
Polygon.cpp
NetExternalComponents.cpp
NetRoutingProperty.cpp
diff --git a/hurricane/src/hurricane/Diagonal.cpp b/hurricane/src/hurricane/Diagonal.cpp
new file mode 100644
index 00000000..3b02597a
--- /dev/null
+++ b/hurricane/src/hurricane/Diagonal.cpp
@@ -0,0 +1,386 @@
+// -*- C++ -*-
+//
+// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved
+//
+// This file is part of Hurricane.
+//
+// Hurricane 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 3 of the
+// License, or (at your option) any later version.
+//
+// Hurricane is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-
+// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU
+// General Public License for more details.
+//
+// You should have received a copy of the Lesser GNU General Public
+// License along with Hurricane. If not, see
+// .
+//
+// +-----------------------------------------------------------------+
+// | H U R R I C A N E |
+// | V L S I B a c k e n d D a t a - B a s e |
+// | |
+// | Authors : Jean-Paul Chaput |
+// | E-mail : Jean-Paul.Chaput@lip6.fr |
+// | =============================================================== |
+// | C++ Module : "./Diagonal.cpp" |
+// +-----------------------------------------------------------------+
+
+
+#include "hurricane/DataBase.h"
+#include "hurricane/Technology.h"
+#include "hurricane/Diagonal.h"
+#include "hurricane/Net.h"
+#include "hurricane/BasicLayer.h"
+#include "hurricane/Layer.h"
+#include "hurricane/Error.h"
+
+
+namespace Hurricane {
+
+
+// -------------------------------------------------------------------
+// Class : "Diagonal".
+
+ Diagonal::Diagonal ( Net* net, const Layer* layer, const Point& source, const Point& target, DbU::Unit width )
+ : Super (net)
+ , _layer (layer)
+ , _source(source)
+ , _target(target)
+ , _width (width)
+ , _B (0)
+ {
+ _updateB();
+ }
+
+
+ Diagonal* Diagonal::create ( Net* net, const Layer* layer, const Point& source, const Point& target, DbU::Unit width )
+ {
+ if (not layer)
+ throw Error( "Diagonal::create(): Can't create, NULL layer" );
+
+ DbU::Unit dx = target.getX() - source.getX();
+ DbU::Unit dy = target.getY() - source.getY();
+
+ dx = (dx < 0) ? -dx : dx;
+ dy = (dy < 0) ? -dy : dy;
+
+ if (dx != dy)
+ throw Error( "Diagonal::create(): Can't create, non-diagonal source/target coordinates" );
+
+ Diagonal* diagonal = new Diagonal ( net, layer, source, target, width );
+
+ diagonal->_postCreate();
+
+ return diagonal;
+ }
+
+
+ DbU::Unit Diagonal::getX () const { return (_target.getX() + _source.getX()) / 2; }
+ DbU::Unit Diagonal::getY () const { return (_target.getX() + _source.getX()) / 2; }
+ DbU::Unit Diagonal::getSourceX () const { return _source.getX(); }
+ DbU::Unit Diagonal::getSourceY () const { return _source.getY(); }
+ DbU::Unit Diagonal::getTargetX () const { return _target.getX(); }
+ DbU::Unit Diagonal::getTargetY () const { return _target.getY(); }
+ Point Diagonal::getSourcePosition () const { return _source; }
+ Point Diagonal::getTargetPosition () const { return _target; }
+ DbU::Unit Diagonal::getWidth () const { return _width; }
+ const Layer* Diagonal::getLayer () const { return _layer; }
+
+
+ Box Diagonal::getBoundingBox() const
+ {
+ return Box( (_source.getX() < _target.getX()) ? _source.getX() : _target.getX()
+ , (_source.getY() < _target.getY()) ? _source.getY() : _target.getY()
+ , (_source.getX() > _target.getX()) ? _source.getX() : _target.getX()
+ , (_source.getY() > _target.getY()) ? _source.getY() : _target.getY()
+ );
+ }
+
+
+ Box Diagonal::getBoundingBox ( const BasicLayer* basicLayer ) const
+ {
+ if (not _layer->contains(basicLayer)) return Box();
+ return getBoundingBox();
+ }
+
+
+ void Diagonal::translate ( const DbU::Unit& dx, const DbU::Unit& dy )
+ {
+ if ( (dx != 0) or (dy != 0) ) {
+ invalidate( true );
+ _source.translate( dx, dy );
+ _target.translate( dx, dy );
+ }
+ }
+
+
+ void Diagonal::setLayer ( const Layer* layer )
+ {
+ if (not layer) throw Error( "Diagonal::setLayer(): Can't set layer, NULL layer" );
+
+ if (layer != _layer) {
+ invalidate( false );
+ _layer = layer;
+ }
+ }
+
+
+ void Diagonal::setSource ( Point source )
+ {
+ if (source == _source) return;
+
+ DbU::Unit dx = _target.getX() - source.getX();
+ DbU::Unit dy = _target.getY() - source.getY();
+ dx = (dx < 0) ? -dx : dx;
+ dy = (dy < 0) ? -dy : dy;
+
+ if (dx != dy)
+ throw Error( "Diagonal::setSource(): Can't set source, non-diagonal points" );
+
+ invalidate(true);
+ _source = source;
+ }
+
+
+ void Diagonal::setTarget ( Point target )
+ {
+ if (target == _target) return;
+
+ DbU::Unit dx = target.getX() - _source.getX();
+ DbU::Unit dy = target.getY() - _source.getY();
+ dx = (dx < 0) ? -dx : dx;
+ dy = (dy < 0) ? -dy : dy;
+
+ if (dx != dy)
+ throw Error( "Diagonal::setSource(): Can't set target, non-diagonal points" );
+
+ invalidate( true );
+ _target = target;
+ }
+
+
+ void Diagonal::setWidth ( DbU::Unit width )
+ {
+ if (width == _width) return;
+
+ invalidate( true );
+ _width = width;
+ _updateB();
+ }
+
+
+ void Diagonal::_updateB ()
+ {
+ _B = (DbU::Unit)( (float)(_width)/sqrt(2) ) - _width/2;
+ if (_B % DbU::getPolygonStep()) {
+ _B += DbU::getPolygonStep() - (_B % DbU::getPolygonStep());
+ }
+
+ if (_B > _width/2) {
+ cerr << Error( "Diagonal::_updateB(): Width is too small invalid polygon on,\n"
+ " %s"
+ , getString(this).c_str() ) << endl;
+ _B = _width/2;
+ }
+ }
+
+
+ size_t Diagonal::getPointsSize () const
+ { return 8; }
+
+
+ Point Diagonal::getPoint ( size_t i ) const
+ {
+ i = i % getPointsSize();
+
+ DbU::Unit dx = _target.getX() - _source.getX();
+ DbU::Unit dy = _target.getY() - _source.getY();
+ DbU::Unit A = _width/2;
+
+ if (not ( (dx > 0) xor (dy > 0) ) ) {
+ Point s = (dx > 0) ? _source : _target;
+ Point t = (dx > 0) ? _target : _source;
+
+ switch ( i ) {
+ case 0: return Point( s.getX()- A, s.getY()-_B );
+ case 1: return Point( s.getX()-_B, s.getY()- A );
+ case 2: return Point( s.getX()+_B, s.getY()- A );
+ case 3: return Point( t.getX()+ A, t.getY()-_B );
+ case 4: return Point( t.getX()+ A, t.getY()+_B );
+ case 5: return Point( t.getX()+_B, t.getY()+ A );
+ case 6: return Point( t.getX()-_B, t.getY()+ A );
+ default:
+ case 7: return Point( s.getX()- A, s.getY()+_B );
+ }
+ } else {
+ Point s = (dx > 0) ? _source : _target;
+ Point t = (dx > 0) ? _target : _source;
+
+ switch ( i ) {
+ case 0: return Point( s.getX()- A, s.getY()-_B );
+ case 1: return Point( t.getX()-_B, t.getY()- A );
+ case 2: return Point( t.getX()+_B, t.getY()- A );
+ case 3: return Point( t.getX()+ A, t.getY()-_B );
+ case 4: return Point( t.getX()+ A, t.getY()+_B );
+ case 5: return Point( s.getX()+_B, s.getY()+ A );
+ case 6: return Point( s.getX()-_B, s.getY()+ A );
+ default:
+ case 7: return Point( s.getX()- A, s.getY()+_B );
+ }
+ }
+ }
+
+
+ void Diagonal::_toJson ( JsonWriter* writer ) const
+ {
+ Inherit::_toJson( writer );
+
+ jsonWrite( writer, "_layer" , _layer->getName() );
+ jsonWrite( writer, "_width" , _width );
+ jsonWrite( writer, "_source", &_source );
+ jsonWrite( writer, "_target", &_target );
+ }
+
+
+ string Diagonal::_getTypeName () const
+ { return _TName( "Diagonal" ); }
+
+
+ string Diagonal::_getString () const
+ {
+ string s = Super::_getString();
+ s.insert( s.length() - 1, " " + getString(_layer->getName()) );
+ s.insert( s.length() - 1
+ , " [" + DbU::getValueString(_source.getX())
+ + " " + DbU::getValueString(_source.getY())
+ + "] [" + DbU::getValueString(_target.getX())
+ + " " + DbU::getValueString(_target.getY())
+ + "]"
+ );
+ return s;
+ }
+
+
+ Record* Diagonal::_getRecord () const
+ {
+ Record* record = Super::_getRecord();
+ if (record) {
+ record->add( getSlot("_layer" , _layer ) );
+ record->add( DbU::getValueSlot("_width" , &_width ) );
+ record->add( getSlot("_source", &_source) );
+ record->add( getSlot("_target", &_target) );
+ }
+ return record;
+ }
+
+
+// -------------------------------------------------------------------
+// Class : "Diagonal::Points_Contour".
+
+ Diagonal::Points_Contour::Locator::Locator ( const Diagonal* diagonal )
+ : PointHL ()
+ , _diagonal(diagonal)
+ , _iPoint (0)
+ { }
+
+
+ PointHL* Diagonal::Points_Contour::Locator::getClone () const
+ { return new Locator(*this); }
+
+
+ Point Diagonal::Points_Contour::Locator::getElement () const
+ { return _diagonal->getPoint(_iPoint); }
+
+
+ bool Diagonal::Points_Contour::Locator::isValid () const
+ { return (_iPoint < _diagonal->getPointsSize()); }
+
+
+ void Diagonal::Points_Contour::Locator::progress ()
+ { if (isValid()) ++_iPoint; }
+
+
+ string Diagonal::Points_Contour::Locator::_getString () const
+ {
+ string s = "<" + _TName("Points_Contour::Locator")
+ + getString(getElement())
+ + ">";
+ return s;
+ }
+
+
+ PointHC* Diagonal::Points_Contour::getClone () const
+ { return new Points_Contour(*this); }
+
+
+ PointHL* Diagonal::Points_Contour::getLocator () const
+ { return new Locator(_diagonal); }
+
+
+ string Diagonal::Points_Contour::_getString () const
+ {
+ string s = "<" + _TName("Points_Contour") + " "
+ + getString(_diagonal)
+ + ">";
+ return s;
+ }
+
+
+// -------------------------------------------------------------------
+// Class : "JsonDiagonal".
+
+
+ Initializer jsonDiagonalInit ( 0 );
+
+
+ void JsonDiagonal::initialize ()
+ { JsonTypes::registerType( new JsonDiagonal (JsonWriter::RegisterMode) ); }
+
+
+ JsonDiagonal::JsonDiagonal ( unsigned long flags )
+ : JsonComponent(flags)
+ {
+ add( "_layer" , typeid(string) );
+ add( "_width" , typeid(uint64_t) );
+ add( "_source", typeid(Point) );
+ add( "_target", typeid(Point) );
+ }
+
+
+ string JsonDiagonal::getTypeName () const
+ { return "Diagonal"; }
+
+
+ JsonDiagonal* JsonDiagonal::clone ( unsigned long flags ) const
+ { return new JsonDiagonal ( flags ); }
+
+
+ void JsonDiagonal::toData ( JsonStack& stack )
+ {
+ check( stack, "JsonDiagonal::toData" );
+ unsigned int jsonId = presetId( stack );
+
+ Diagonal* diagonal = Diagonal::create
+ ( get(stack,".Net")
+ , DataBase::getDB()->getTechnology()->getLayer( get(stack,"_layer") )
+ , get(stack,".Point")
+ , get(stack,".Point")
+ , DbU::fromDb( get(stack,"_width" ) )
+ );
+
+ JsonNet* jnet = jget( stack );
+ if (jnet) {
+ jnet->addHookLink( diagonal->getBodyHook (), jsonId, get(stack,"_bodyHook" ) );
+ } else {
+ cerr << Error( "Jsondiagonal::toData(): Missing (Json)Net in stack context." ) << endl;
+ }
+
+ // Hook/Ring rebuild are done as a post-process.
+ update( stack, diagonal );
+}
+
+
+} // Hurricane namespace.
diff --git a/hurricane/src/hurricane/hurricane/Diagonal.h b/hurricane/src/hurricane/hurricane/Diagonal.h
new file mode 100644
index 00000000..4ae70c9f
--- /dev/null
+++ b/hurricane/src/hurricane/hurricane/Diagonal.h
@@ -0,0 +1,158 @@
+// -*- C++ -*-
+//
+// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved
+//
+// This file is part of Hurricane.
+//
+// Hurricane 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 3 of the
+// License, or (at your option) any later version.
+//
+// Hurricane is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-
+// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU
+// General Public License for more details.
+//
+// You should have received a copy of the Lesser GNU General Public
+// License along with Hurricane. If not, see
+// .
+//
+// +-----------------------------------------------------------------+
+// | H U R R I C A N E |
+// | V L S I B a c k e n d D a t a - B a s e |
+// | |
+// | Authors : Jean-Paul Chaput |
+// | E-mail : Jean-Paul.Chaput@lip6.fr |
+// | =============================================================== |
+// | C++ Header : "./hurricane/Diagonal.h" |
+// +-----------------------------------------------------------------+
+
+
+#ifndef HURRICANE_DIAGONAL_H
+#define HURRICANE_DIAGONAL_H
+
+#include "hurricane/Points.h"
+#include "hurricane/Component.h"
+
+
+namespace Hurricane {
+
+ class Layer;
+
+
+// -------------------------------------------------------------------
+// Class : "Diagonal".
+
+ class Diagonal : public Component {
+ public:
+ typedef Component Super;
+
+ public:
+ class Points_Contour : public PointHC {
+ public:
+ class Locator : public PointHL {
+ public:
+ Locator ( const Diagonal* );
+ inline Locator ( const Locator& );
+ virtual Point getElement () const;
+ virtual PointHL* getClone () const;
+ virtual bool isValid () const;
+ virtual void progress ();
+ virtual string _getString () const;
+ protected:
+ const Diagonal* _diagonal;
+ size_t _iPoint;
+ };
+ public:
+ inline Points_Contour ( const Diagonal* );
+ inline Points_Contour ( const Points_Contour& );
+ virtual PointHC* getClone () const;
+ virtual PointHL* getLocator () const;
+ virtual string _getString () const;
+ protected:
+ const Diagonal* _diagonal;
+ };
+
+ public:
+ static Diagonal* create ( Net*, const Layer*, const Point& source, const Point& target, DbU::Unit width );
+ // Accessors.
+ virtual DbU::Unit getX () const;
+ virtual DbU::Unit getY () const;
+ virtual DbU::Unit getSourceX () const;
+ virtual DbU::Unit getSourceY () const;
+ virtual DbU::Unit getTargetX () const;
+ virtual DbU::Unit getTargetY () const;
+ virtual Point getSourcePosition () const;
+ virtual Point getTargetPosition () const;
+ virtual Box getBoundingBox () const;
+ virtual Box getBoundingBox ( const BasicLayer* ) const;
+ size_t getPointsSize () const;
+ Point getPoint ( size_t i ) const;
+ DbU::Unit getWidth () const;
+ virtual const Layer* getLayer () const;
+ inline Points getContour () const;
+ // Mutators.
+ void setLayer ( const Layer* );
+ void setWidth ( DbU::Unit );
+ virtual void translate ( const DbU::Unit& dx, const DbU::Unit& dy );
+ void setSource ( Point );
+ void setTarget ( Point );
+ // Hurricane management.
+ virtual void _toJson ( JsonWriter* ) const;
+ static JsonObject* getJsonObject ( unsigned long flags );
+ virtual string _getTypeName () const;
+ virtual string _getString () const;
+ virtual Record* _getRecord () const;
+ protected:
+ Diagonal ( Net*, const Layer*, const Point& source, const Point& target, DbU::Unit width );
+ void _updateB ();
+ private:
+ const Layer* _layer;
+ Point _source;
+ Point _target;
+ DbU::Unit _width;
+ DbU::Unit _B; // octagon half Y.
+ };
+
+
+ inline Points Diagonal::getContour () const { return Points_Contour(this); }
+
+
+ inline Diagonal::Points_Contour::Locator::Locator ( const Locator &locator )
+ : PointHL ()
+ , _diagonal(locator._diagonal)
+ , _iPoint (locator._iPoint)
+ { }
+
+
+ inline Diagonal::Points_Contour::Points_Contour ( const Diagonal* diagonal )
+ : PointHC ()
+ , _diagonal(diagonal)
+ { }
+
+
+ inline Diagonal::Points_Contour::Points_Contour ( const Points_Contour& other )
+ : PointHC ()
+ , _diagonal(other._diagonal)
+ { }
+
+
+// -------------------------------------------------------------------
+// Class : "JsonRoutingDiagonal".
+
+ class JsonDiagonal : public JsonComponent {
+ public:
+ static void initialize ();
+ JsonDiagonal ( unsigned long flags );
+ virtual std::string getTypeName () const;
+ virtual JsonDiagonal* clone ( unsigned long ) const;
+ virtual void toData ( JsonStack& );
+ };
+
+} // Hurricane namespace.
+
+
+INSPECTOR_P_SUPPORT(Hurricane::Diagonal);
+
+#endif // HURRICANE_DIAGONAL_H
diff --git a/hurricane/src/hurricane/hurricane/Points.h b/hurricane/src/hurricane/hurricane/Points.h
index ddee6136..28668c40 100644
--- a/hurricane/src/hurricane/hurricane/Points.h
+++ b/hurricane/src/hurricane/hurricane/Points.h
@@ -1,75 +1,59 @@
-// ****************************************************************************************************
-// File: ./hurricane/Points.h
-// Authors: R. Escassut
+// -*- C++ -*-
+//
// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved
//
// This file is part of Hurricane.
//
-// Hurricane 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 3 of the
+// Hurricane 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 3 of the
// License, or (at your option) any later version.
//
-// Hurricane 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 Lesser GNU
+// Hurricane is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-
+// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU
// General Public License for more details.
//
-// You should have received a copy of the Lesser GNU General Public License along with Hurricane. If
-// not, see .
-// ****************************************************************************************************
+// You should have received a copy of the Lesser GNU General Public
+// License along with Hurricane. If not, see
+// .
+//
+// +-----------------------------------------------------------------+
+// | H U R R I C A N E |
+// | V L S I B a c k e n d D a t a - B a s e |
+// | |
+// | Author : Remy Escassut |
+// | E-mail : Jean-Paul.Chaput@lip6.fr |
+// | =============================================================== |
+// | C++ Header : "./hurricane/Points.h" |
+// +-----------------------------------------------------------------+
-#ifndef HURRICANE_POINTS
-#define HURRICANE_POINTS
+
+#ifndef HURRICANE_POINTS_H
+#define HURRICANE_POINTS_H
#include "hurricane/Collection.h"
#include "hurricane/Point.h"
+
namespace Hurricane {
+ typedef GenericCollection Points;
+ typedef GenericLocator PointLocator;
+ typedef GenericFilter PointFilter;
+ typedef Filter PointHF;
+ typedef Locator PointHL;
+ typedef Collection PointHC;
-// ****************************************************************************************************
-// Points declaration
-// ****************************************************************************************************
-
-typedef GenericCollection Points;
+#define for_each_point(point, points) \
+{ \
+ PointLocator _locator = points.getLocator(); \
+ while (_locator.isValid()) { \
+ Point point = _locator.getElement(); \
+ _locator.progress();
+} // Hurricane namespace.
-// ****************************************************************************************************
-// PointLocator declaration
-// ****************************************************************************************************
-
-typedef GenericLocator PointLocator;
-
-
-
-// ****************************************************************************************************
-// PointFilter declaration
-// ****************************************************************************************************
-
-typedef GenericFilter PointFilter;
-
-
-
-// ****************************************************************************************************
-// for_each_point declaration
-// ****************************************************************************************************
-
-#define for_each_point(point, points)\
-/************************************/\
-{\
- PointLocator _locator = points.getLocator();\
- while (_locator.isValid()) {\
- Point point = _locator.getElement();\
- _locator.progress();
-
-
-
-} // End of Hurricane namespace.
-
-#endif // HURRICANE_POINTS
-
-
-// ****************************************************************************************************
-// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved
-// ****************************************************************************************************
+#endif // HURRICANE_POINTS_H
diff --git a/hurricane/src/hurricane/hurricane/Polygon.h b/hurricane/src/hurricane/hurricane/Polygon.h
index 28450d32..03542970 100644
--- a/hurricane/src/hurricane/hurricane/Polygon.h
+++ b/hurricane/src/hurricane/hurricane/Polygon.h
@@ -41,11 +41,6 @@ namespace Hurricane {
class Layer;
-
- typedef Hurricane::Filter PointHF;
- typedef Hurricane::Locator PointHL;
- typedef Hurricane::Collection PointHC;
-
class Polygon : public Component {
public:
diff --git a/hurricane/src/isobar/CMakeLists.txt b/hurricane/src/isobar/CMakeLists.txt
index e6842b7b..22612fe2 100644
--- a/hurricane/src/isobar/CMakeLists.txt
+++ b/hurricane/src/isobar/CMakeLists.txt
@@ -51,6 +51,7 @@
PyHook.cpp
PyHookCollection.cpp
PyPad.cpp
+ PyDiagonal.cpp
PyPath.cpp
PyPin.cpp
PyPinPlacementStatus.cpp
@@ -119,6 +120,7 @@
hurricane/isobar/PyHookCollection.h
hurricane/isobar/PyPad.h
hurricane/isobar/PyPath.h
+ hurricane/isobar/PyDiagonal.h
hurricane/isobar/PyPin.h
hurricane/isobar/PyPinPlacementStatus.h
hurricane/isobar/PyPinDirection.h
diff --git a/hurricane/src/isobar/PyDiagonal.cpp b/hurricane/src/isobar/PyDiagonal.cpp
new file mode 100644
index 00000000..558fc9f6
--- /dev/null
+++ b/hurricane/src/isobar/PyDiagonal.cpp
@@ -0,0 +1,272 @@
+// -*- C++ -*-
+//
+// This file is part of the Coriolis Software.
+// Copyright (c) UPMC 2006-2018, All Rights Reserved
+//
+// +-----------------------------------------------------------------+
+// | C O R I O L I S |
+// | I s o b a r - Hurricane / Python Interface |
+// | |
+// | Author : Jean-Paul CHAPUT |
+// | E-mail : Jean-Paul.Chaput@lip6.fr |
+// | =============================================================== |
+// | C++ Module : "./PyDiagonal.cpp" |
+// +-----------------------------------------------------------------+
+
+
+#include "hurricane/isobar/PyNet.h"
+#include "hurricane/isobar/PyLayer.h"
+#include "hurricane/isobar/PyPoint.h"
+#include "hurricane/isobar/PyBox.h"
+#include "hurricane/isobar/PyDiagonal.h"
+
+
+namespace Isobar {
+
+using namespace Hurricane;
+
+extern "C" {
+
+
+#undef ACCESS_OBJECT
+#undef ACCESS_CLASS
+#define ACCESS_OBJECT _baseObject._baseObject._object
+#define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject._baseObject)
+#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Diagonal,diagonal,function)
+
+
+// +=================================================================+
+// | "PyDiagonal" Python Module Code Part |
+// +=================================================================+
+
+#if defined(__PYTHON_MODULE__)
+
+ // Standard Accessors (Attributes).
+ DirectGetLongAttribute(PyDiagonal_getX , getX , PyDiagonal, Diagonal)
+ DirectGetLongAttribute(PyDiagonal_getY , getY , PyDiagonal, Diagonal)
+ DirectGetLongAttribute(PyDiagonal_getSourceX , getSourceX , PyDiagonal, Diagonal)
+ DirectGetLongAttribute(PyDiagonal_getSourceY , getSourceY , PyDiagonal, Diagonal)
+ DirectGetLongAttribute(PyDiagonal_getTargetX , getTargetX , PyDiagonal, Diagonal)
+ DirectGetLongAttribute(PyDiagonal_getTargetY , getTargetY , PyDiagonal, Diagonal)
+ DirectGetLongAttribute(PyDiagonal_getWidth , getWidth , PyDiagonal, Diagonal)
+ DirectGetUIntAttribute(PyDiagonal_getPointsSize, getPointsSize, PyDiagonal, Diagonal)
+ DirectSetLongAttribute(PyDiagonal_setWidth , setWidth , PyDiagonal, Diagonal)
+
+ // Standard Destroy (Attribute).
+ DBoDestroyAttribute(PyDiagonal_destroy, PyDiagonal)
+
+
+ static PyObject* PyDiagonal_create ( PyObject*, PyObject *args )
+ {
+ cdebug_log(20,0) << "PyDiagonal_create()" << endl;
+
+ PyObject* arg0 = NULL;
+ PyObject* arg1 = NULL;
+ PyObject* arg2 = NULL;
+ PyObject* arg3 = NULL;
+ PyObject* arg4 = NULL;
+ Diagonal* diagonal = NULL;
+
+ HTRY
+ __cs.init( "Diagonal.create" );
+ if (not PyArg_ParseTuple(args,"O&O&O&O&O&:Diagonal.create"
+ ,Converter,&arg0
+ ,Converter,&arg1
+ ,Converter,&arg2
+ ,Converter,&arg3
+ ,Converter,&arg4
+ )) {
+ PyErr_SetString( ConstructorError, "Diagonal.create(): Invalid number of parameters." );
+ return NULL;
+ }
+
+ if ( __cs.getObjectIds() == ":ent:layer:point:point:int") {
+ diagonal = Diagonal::create( PYNET_O(arg0)
+ , PYLAYER_O(arg1)
+ , *PYPOINT_O(arg2)
+ , *PYPOINT_O(arg3)
+ , PyAny_AsLong(arg4)
+ );
+ } else {
+ PyErr_SetString( ConstructorError, "Diagonal.create(): Bad type of parameter(s)." );
+ return NULL;
+ }
+ HCATCH
+
+ return PyDiagonal_Link(diagonal);
+ }
+
+
+ static PyObject* PyDiagonal_getSourcePosition ( PyDiagonal *self )
+ {
+ cdebug_log(20,0) << "PyDiagonal_getSourcePosition()" << endl;
+ METHOD_HEAD( "Diagonal.getSourcePosition()" )
+
+ PyPoint* pyPoint = PyObject_NEW ( PyPoint, &PyTypePoint );
+ if (pyPoint == NULL) return NULL;
+
+ HTRY
+ pyPoint->_object = new Point ( diagonal->getSourcePosition() );
+ HCATCH
+
+ return (PyObject*)pyPoint;
+ }
+
+
+ static PyObject* PyDiagonal_getTargetPosition ( PyDiagonal *self )
+ {
+ cdebug_log(20,0) << "PyDiagonal_getTargetPosition()" << endl;
+ METHOD_HEAD( "Diagonal.getTargetPosition()" )
+
+ PyPoint* pyPoint = PyObject_NEW ( PyPoint, &PyTypePoint );
+ if (pyPoint == NULL) return NULL;
+
+ HTRY
+ pyPoint->_object = new Point ( diagonal->getTargetPosition() );
+ HCATCH
+
+ return (PyObject*)pyPoint;
+ }
+
+
+ static PyObject* PyDiagonal_getPoint ( PyDiagonal *self, PyObject* args )
+ {
+ cdebug_log(20,0) << "PyDiagonal_getPoint()" << endl;
+ METHOD_HEAD( "Diagonal.getTargetPoint()" )
+
+ PyPoint* pyPoint = PyObject_NEW ( PyPoint, &PyTypePoint );
+ if (pyPoint == NULL) return NULL;
+
+ HTRY
+ int i = 0;
+ if (not PyArg_ParseTuple( args, "i:Diagonal.getPoint", &i)) {
+ PyErr_SetString( ConstructorError, "Diagonal.getPoint(): Invalid parameter type." );
+ return NULL;
+ }
+ pyPoint->_object = new Point ( diagonal->getPoint(i) );
+ HCATCH
+
+ return (PyObject*)pyPoint;
+ }
+
+
+ static PyObject* PyDiagonal_getBoundingBox( PyDiagonal *self )
+ {
+ cdebug_log(20,0) << "PyDiagonal_getBoundingBox()" << endl;
+
+ METHOD_HEAD ( "Diagonal.BoundingBox()" )
+
+ PyBox* pyBox = PyObject_NEW ( PyBox, &PyTypeBox );
+ if (pyBox == NULL) { return NULL; }
+
+ HTRY
+ pyBox->_object = new Box ( diagonal->getBoundingBox() );
+ HCATCH
+
+ return ( (PyObject*)pyBox );
+ }
+
+
+ static PyObject* PyDiagonal_setSource ( PyDiagonal *self, PyObject* args )
+ {
+ cdebug_log(20,0) << "Diagonal.setSource()" << endl;
+ HTRY
+ METHOD_HEAD( "Diagonal.setSource()" )
+
+ PyPoint* point = NULL;
+ if (not ParseOneArg("Diagonal.setSource", args, POINT_ARG, (PyObject**)&point))
+ return NULL;
+ diagonal->setSource(*PYPOINT_O(point));
+ HCATCH
+ Py_RETURN_NONE;
+ }
+
+
+ static PyObject* PyDiagonal_setTarget ( PyDiagonal *self, PyObject* args )
+ {
+ cdebug_log(20,0) << "Diagonal.setTarget()" << endl;
+ HTRY
+ METHOD_HEAD( "Diagonal.setTarget()" )
+
+ PyPoint* point = NULL;
+ if (not ParseOneArg("Diagonal.setTarget", args, POINT_ARG, (PyObject**)&point))
+ return NULL;
+ diagonal->setTarget(*PYPOINT_O(point));
+ HCATCH
+ Py_RETURN_NONE;
+ }
+
+
+ static PyObject* PyDiagonal_translate ( PyDiagonal *self, PyObject* args )
+ {
+ cdebug_log(20,0) << "PyDiagonal_translate ()" << endl;
+
+ HTRY
+ METHOD_HEAD ( "Diagonal.translate()" )
+ PyObject* arg0 = NULL;
+ PyObject* arg1 = NULL;
+ __cs.init ("Diagonal.translate");
+ if (PyArg_ParseTuple(args,"O&O&:Diagonal.translate", Converter, &arg0, Converter, &arg1)) {
+ if (__cs.getObjectIds() == INTS2_ARG) diagonal->translate( PyAny_AsLong(arg0), PyAny_AsLong(arg1) );
+ else {
+ PyErr_SetString ( ConstructorError, "Diagonal.translate(): Invalid type for parameter(s)." );
+ return NULL;
+ }
+ } else {
+ PyErr_SetString ( ConstructorError, "Diagonal.translate(): Invalid number of parameters." );
+ return NULL;
+ }
+ HCATCH
+
+ Py_RETURN_NONE;
+ }
+
+
+ // ---------------------------------------------------------------
+ // PyDiagonal Attribute Method table.
+
+ PyMethodDef PyDiagonal_Methods[] =
+ { { "create" , (PyCFunction)PyDiagonal_create , METH_VARARGS|METH_STATIC
+ , "Create a new Diagonal." }
+ , { "getX" , (PyCFunction)PyDiagonal_getX , METH_NOARGS , "Return the Diagonal X value." }
+ , { "getY" , (PyCFunction)PyDiagonal_getY , METH_NOARGS , "Return the Diagonal Y value." }
+ , { "getSourceX" , (PyCFunction)PyDiagonal_getSourceX , METH_NOARGS , "Return the Diagonal source X value." }
+ , { "getSourceY" , (PyCFunction)PyDiagonal_getSourceY , METH_NOARGS , "Return the Diagonal source Y value." }
+ , { "getTargetX" , (PyCFunction)PyDiagonal_getTargetX , METH_NOARGS , "Return the Diagonal target X value." }
+ , { "getTargetY" , (PyCFunction)PyDiagonal_getTargetY , METH_NOARGS , "Return the Diagonal target Y value." }
+ , { "getSourcePosition", (PyCFunction)PyDiagonal_getSourcePosition, METH_NOARGS , "Return the Diagonal source position." }
+ , { "getTargetPosition", (PyCFunction)PyDiagonal_getTargetPosition, METH_NOARGS , "Return the Diagonal target position." }
+ , { "getWidth" , (PyCFunction)PyDiagonal_getWidth , METH_NOARGS , "Return the Diagonal wire width." }
+ , { "getPointsSize" , (PyCFunction)PyDiagonal_getPointsSize , METH_NOARGS , "Return the Diagonal polygon number of points (vertexes)." }
+ , { "getPoint" , (PyCFunction)PyDiagonal_getPoint , METH_VARARGS, "Return the Diagonal polygon point at index i." }
+ , { "getBoundingBox" , (PyCFunction)PyDiagonal_getBoundingBox , METH_NOARGS , "Return the Diagonal Bounding Box." }
+ , { "translate" , (PyCFunction)PyDiagonal_translate , METH_VARARGS, "Translates the Diagonal of dx and dy." }
+ , { "setWidth" , (PyCFunction)PyDiagonal_setWidth , METH_VARARGS, "Set the Diagonal wire width." }
+ , { "setSource" , (PyCFunction)PyDiagonal_setSource , METH_VARARGS, "Set the Diagonal source point (must be diagonal to target)." }
+ , { "setTarget" , (PyCFunction)PyDiagonal_setTarget , METH_VARARGS, "Set the Diagonal target point (must be diagonal to source)." }
+ , { "destroy" , (PyCFunction)PyDiagonal_destroy , METH_NOARGS
+ , "Destroy associated hurricane object, the python object remains." }
+ , {NULL, NULL, 0, NULL} /* sentinel */
+ };
+
+
+ DBoDeleteMethod(Diagonal)
+ PyTypeObjectLinkPyType(Diagonal)
+
+
+#else // Python Module Code Part.
+
+// +=================================================================+
+// | "PyDiagonal" Shared Library Code Part |
+// +=================================================================+
+
+
+ // Link/Creation Method.
+ DBoLinkCreateMethod(Diagonal)
+ PyTypeInheritedObjectDefinitions(Diagonal, Component)
+
+#endif // Shared Library Code Part.
+
+} // extern "C".
+
+} // Isobar namespace.
diff --git a/hurricane/src/isobar/PyHurricane.cpp b/hurricane/src/isobar/PyHurricane.cpp
index b0b5017a..240470c0 100644
--- a/hurricane/src/isobar/PyHurricane.cpp
+++ b/hurricane/src/isobar/PyHurricane.cpp
@@ -72,6 +72,7 @@
#include "hurricane/isobar/PyHorizontal.h"
#include "hurricane/isobar/PyVertical.h"
#include "hurricane/isobar/PyPad.h"
+#include "hurricane/isobar/PyDiagonal.h"
#include "hurricane/isobar/PyPolygon.h"
#include "hurricane/isobar/PyPath.h"
#include "hurricane/isobar/PyOccurrence.h"
@@ -565,6 +566,7 @@ extern "C" {
PyComponent_LinkPyType ();
PySegment_LinkPyType ();
PyPad_LinkPyType ();
+ PyDiagonal_LinkPyType ();
PyRoutingPad_LinkPyType ();
PyVertical_LinkPyType ();
PyHorizontal_LinkPyType ();
@@ -655,7 +657,8 @@ extern "C" {
PYTYPE_READY_SUB ( Pin , Contact )
PYTYPE_READY_SUB ( Plug , Component)
PYTYPE_READY_SUB ( Pad , Component)
- PYTYPE_READY_SUB ( Polygon , Component)
+ PYTYPE_READY_SUB ( Diagonal , Component)
+ PYTYPE_READY_SUB ( Polygon , Component)
// Identifier string can take up to 10 characters !
__cs.addType ( "intv" , &PyTypeInterval , "" , false );
@@ -707,6 +710,7 @@ extern "C" {
__cs.addType ( "rp" , &PyTypeRoutingPad , "" , false, "comp" );
__cs.addType ( "segment" , &PyTypeSegment , "" , false, "comp" );
__cs.addType ( "pad " , &PyTypePad , "" , false, "comp" );
+ __cs.addType ( "diagonal" , &PyTypeDiagonal , "" , false, "comp" );
__cs.addType ( "polygon" , &PyTypePolygon , "" , false, "comp" );
__cs.addType ( "segmentCol" , &PyTypeSegmentCollection , "" , false );
__cs.addType ( "db" , &PyTypeDataBase , "" , false );
@@ -806,8 +810,10 @@ extern "C" {
PyModule_AddObject ( module, "Pin" , (PyObject*)&PyTypePin );
Py_INCREF ( &PyTypePad );
PyModule_AddObject ( module, "Pad" , (PyObject*)&PyTypePad );
+ Py_INCREF ( &PyTypeDiagonal );
+ PyModule_AddObject ( module, "Diagonal" , (PyObject*)&PyTypeDiagonal );
Py_INCREF ( &PyTypePolygon );
- PyModule_AddObject ( module, "Polygon" , (PyObject*)&PyTypePolygon );
+ PyModule_AddObject ( module, "Polygon" , (PyObject*)&PyTypePolygon );
PyObject* dictionnary = PyModule_GetDict ( module );
diff --git a/hurricane/src/isobar/hurricane/isobar/PyDiagonal.h b/hurricane/src/isobar/hurricane/isobar/PyDiagonal.h
new file mode 100644
index 00000000..0b81f6c7
--- /dev/null
+++ b/hurricane/src/isobar/hurricane/isobar/PyDiagonal.h
@@ -0,0 +1,56 @@
+// -*- C++ -*-
+//
+// This file is part of the Coriolis Software.
+// Copyright (c) UPMC 2006-2018, All Rights Reserved
+//
+// +-----------------------------------------------------------------+
+// | C O R I O L I S |
+// | I s o b a r - Hurricane / Python Interface |
+// | |
+// | Author : Jean-Paul CHAPUT |
+// | E-mail : Jean-Paul.Chaput@lip6.fr |
+// | =============================================================== |
+// | C++ Header : "./hurricane/isobar/PyDiagonal.h" |
+// +-----------------------------------------------------------------+
+
+
+#ifndef PY_DIAGONAL_H
+#define PY_DIAGONAL_H
+
+#include "hurricane/isobar/PyComponent.h"
+#include "hurricane/Diagonal.h"
+
+
+namespace Isobar {
+
+ extern "C" {
+
+
+// -------------------------------------------------------------------
+// Python Object : "PyDiagonal".
+
+ typedef struct {
+ PyComponent _baseObject;
+ } PyDiagonal;
+
+
+// -------------------------------------------------------------------
+// Functions & Types exported to "PyHurricane.ccp".
+
+ extern PyTypeObject PyTypeDiagonal;
+ extern PyMethodDef PyDiagonal_Methods[];
+
+ extern PyObject* PyDiagonal_Link ( Hurricane::Diagonal* object );
+ extern void PyDiagonal_LinkPyType ();
+
+
+#define IsPyDiagonal(v) ( (v)->ob_type == &PyTypeDiagonal )
+#define PYDIAGONAL(v) ( (PyDiagonal*)(v) )
+#define PYDIAGONAL_O(v) ( PYDIAGONAL(v)->_baseObject._baseObject._object )
+
+
+ } // extern "C".
+
+} // Isobar namespace.
+
+#endif // PY_DIAGONAL_H
diff --git a/hurricane/src/viewer/CellWidget.cpp b/hurricane/src/viewer/CellWidget.cpp
index 8c4e02c2..2083805f 100644
--- a/hurricane/src/viewer/CellWidget.cpp
+++ b/hurricane/src/viewer/CellWidget.cpp
@@ -39,6 +39,7 @@
#include "hurricane/Vertical.h"
#include "hurricane/Contact.h"
#include "hurricane/Pad.h"
+#include "hurricane/Diagonal.h"
#include "hurricane/Polygon.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/ExtensionGo.h"
@@ -665,6 +666,20 @@ namespace Hurricane {
static QRect rectangle;
static unsigned int state;
+ const Diagonal* diagonal = dynamic_cast(go);
+ if (diagonal) {
+ _goCount++;
+ Box bb = transformation.getBox(diagonal->getBoundingBox(basicLayer));
+ rectangle = _cellWidget->dbuToScreenRect( bb );
+ if ( (rectangle.width() > 4) and (rectangle.height() > 4) ) {
+ QPolygon contour;
+ for ( Point point : diagonal->getContour() )
+ contour << _cellWidget->dbuToScreenPoint( point );
+ _cellWidget->drawScreenPolygon( contour );
+ }
+ return;
+ }
+
const Polygon* polygon = dynamic_cast(go);
if (polygon) {
_goCount++;