// ************************************************************
//  History
//  *   22-JAN-1996 / R. Werner / DEC MS 2.1 (without idm)
//  *                 start option '-idm_slave'
//  *   05-Jun-1996 / bit      
//  *                 input config modified
// 
// ************************************************************
//                Global parameters
// ============================================================
//
include !ideas_msg.txt
include #bearun/msc/mess.lan

VAR_ID_global_Model_Save = false  
   // = true, when IPC with I-DEAS
   //         and no idm (start option: 'ideas_slave')
   //         and no modification of key dimensions

// configuration parameters
// ========================
   ID_ITALIC =  0
   ID_FONT   = "Helvetica"
   ID_MODUS   = 1.000000  // default

// title block  
// -----------
// derived from ID_DRAW in configuration file 
//    0: no title block 
//    1: Engineering Layout title block 
//    2: I-DEAS title block  
//       (only the first time and keep modifications)
//    3: I-DEAS title block 
//       Get actual from I-DEAS

VAR_ID_global_drawing = 0

// Mittellinie Ueberstand 
// ----------------------
// derived from ID_CENTERLINE_ADD in configuration file
// Mittellinie Ueberstand, wenn ID_CENTERLINE_ADD
//  = 0 --> Mittellinie ohne Ueberstand
//  = 1 --> Mittellinie mit  Ueberstand

VAR_ID_global_ClineAdd = 0 

// Masse: Aenderbarkeit von Masstexthoehe und -position
// ----------------------------------------------------
// derived from Parameter ID_MEASURE_MODIFY in configuration file
// VAR_ID_global_MeasModify 0 --> Wird immer von I-DEAS uebernommen
// VAR_ID_global_MeasModify 1 --> Aenderungen Text Hoehe und
//                                Position bleiben erhalten
// VAR_ID_global_MeasModify 2 --> Alle Aenderungen bleiben erhalten

VAR_ID_global_MeasModify = 2
VAR_ID_measure_old = 0  // Zeiger auf altes Mass
                        // oder Null

// Texte: Aenderbarkeit von Texten
// ----------------------------------------------------
// derived from Parameter ID_TEXT_MODIFY in configuration file
// VAR_ID_global_TextModify 0 --> Wird immer von I-DEAS uebernommen
// VAR_ID_global_TextModify 1 --> nur Textinhalt wird geaendert
// VAR_ID_global_TextModify 2 --> Alle Aenderungen bleiben erhalten

VAR_ID_global_TextModify = 2
VAR_ID_text_old = 0    // Zeiger auf alten Text
                       // oder Null

// Texte: Aenderbarkeit von Symbolen
// ----------------------------------------------------
// derived from Parameter ID_TEXT_MODIFY in configuration file
// VAR_ID_global_SymbolModify 0 --> Wird immer von I-DEAS uebernommen
// VAR_ID_global_SymbolModify 1 --> nur Textinhalt wird geaendert
// VAR_ID_global_SymbolModify 2 --> Alle Aenderungen bleiben erhalten

VAR_ID_global_SymbolModify = 2

VAR_ID_symbol_old = 0  // Zeiger auf altes Symbol
                       // oder Null
 
// Aenderbarkeit von Ansichten
// ----------------------------------------------------
// derived from Parameter ID_VIEW_MODIFY in configuration file
// VAR_ID_global_ViewModify 0 --> Wird immer von I-DEAS uebernommen
// VAR_ID_global_ViewModify 1 --> Alle Aenderungen bleiben erhalten

VAR_ID_global_ViewModify = 1
 
// Linestyle-Aenderbarkeit
// -----------------------
// derived from Parameter ID_LINESTYLE_MODIFY in configuration file
// VAR_ID_global_LineStyle 0 --> Wird immer von I-DEAS uebernommen
// VAR_ID_global_LineStyle 1 --> Aenderungen bleiben erhalten

VAR_ID_global_LineStyle = 1


// Delete status of Ideas entities 
// --------------------------------
// Treating deleted elements (Status von geloeschten Elementen)
//    ID_KEEP_DELETE 0 --> Get from SIGRAPH-IDEAS = make them visible
//                         Geloeschte Elemente werden sichtbar.
//    ID_KEEP_DELETE 1 --> Keep SIGRAPH-DESIGN modifications
//                         Geloeschte Elemente bleiben unsichtbar.
// 
//   1. Moeglichkeit  (VAR_ID_KeepDelete = 0)
//      Wurden in Design Transfer-Elemente geloescht, so werden
//      beim erneuten Transfer diese Elemente wieder sichtbar.
//      Hinweis: 
//        Dadurch koennen Elemente, die durch nachtraegliche 
//        Manipulationen in Design unsichtbar wurden, 
//        wieder sichtbar werden. 
//        Beispiel:  Fasen / Runden von Transfer-Linien
//        Nach einem erneuter Transfer sind die "alten" Linien
//        wieder sichtbar und scheinbar doppelt vorhanden.
// 
//   2. Moeglichkeit  (VAR_ID_KeepDelete = 1)
//      Wurden in Design Transfer-Elemente geloescht, so bleiben 
//      beim erneuten Transfer diese Elemente unsichtbar.
//      D.h.:
//      - Originalzustand in IDEAS wird nicht hergestellt
//      - Manipulationen (z.B. Fasen und Runden) bleiben erhalten
//        --> nach Fasen und Runden sind keine Linien doppelt vorhanden.
//        

VAR_ID_KeepDelete = 1


// ************************************************************
//                Initialisierung: global datas
// ============================================================
//
// Header Informationen aus I-DEAS
// -------------------------------

VAR_ID_global_Pjname     = " "  /* Project name                           */
VAR_ID_global_MFname     = " "  /* Model file name                        */
VAR_ID_global_TopFname   = " "  /* Top file name                          */
VAR_ID_global_MFdesc     = " "  /* Model file description                 */
VAR_ID_global_CrtPprg    = " "  /* Program which created DB               */
VAR_ID_global_CrtDBdate  = " "  /* Date DB created                        */
VAR_ID_global_CrtDBtime  = " "  /* Time DB created                        */
VAR_ID_global_iMajRevNum = 0    /* Major revision number i.e  7           */
VAR_ID_global_iMinRevNum = 0    /* Minor revision number i.e    0         */
                                /* This example indicates rel 7.0         */
VAR_ID_global_SaveDBdate = " "  /* Date DB saved                          */
VAR_ID_global_SaveDBtime = " "  /* Time DB saved                          */
VAR_ID_global_CrtPrgUnv  = " "  /* Program which created puf              */
VAR_ID_global_UnvWrtDate = " "  /* Puf write data                         */
VAR_ID_global_UnvWrtTime = " "  /* Puf write time                         */

//
// Drawing Informationen aus I-DEAS
// --------------------------------
VAR_ID_global_iDrawId    = 0     /* Drawing Id                            */
VAR_ID_global_iSize      = 0     /* Drawing size                          */
VAR_ID_global_cDrawName  = " "   /* Drawing name                          */
VAR_ID_global_dDefScale  = 0.0   /* Drawing layout view default scale     */
VAR_ID_global_dDrawHor   = 0.0   /* Drawing horizontal length             */
VAR_ID_global_dDrawVer   = 0.0   /* Drawing vertical length               */


// ************************************************************
//                Initialisierung: Design-Spezifika
// ============================================================
//
// world
// ----- 

VAR_ID_global_name_ideas = " "    // name of VAR_ID_global_world_ideas, VAR_ID_global_orig_ideas,
                                  //         VAR_ID_global_layer
VAR_ID_global_world_ideas = 0     // world under top = 1. world der Zeichnung
                                  // where all elements of a drawing coming 
                                  // from I-DEAS have references to (in/directly)
VAR_ID_global_orig_ideas  = 0     // Ursprung von VAR_ID_global_world_ideas
                        

// Aktuellen Zeichnungsansichten 
// ----------------------------- 
// Fuer jede uebertragene Ansicht wird eine world definiert
//    - world der view: VAR_ID_global_world_view
//    - Ursprung ist relativ zu VAR_ID_global_world_ideas
//    - Besitzt Massstabsfaktor der View

VAR_ID_global_world_view = 0   // aktuelle world mit Namen "VAR_ID_global_name_view"
VAR_ID_global_name_view = " "  // Name der aktuellen world
                               // Name = "Name der Ansicht"
                               //     z.B. FRONT, ISO, TOP
VAR_ID_global_type_view = " "  // type of actual view:  int  0, 1 , 2 , ... , 13
VAR_ID_global_orig_view = 0    // Ursprung der aktuellen world

// Layer
// -----

VAR_ID_global_layer = " "  // layer fuer Zeichnung mit Name = VAR_ID_global_name_ideas 
                                 // where all elements of a drawing coming 
                                 // from I-DEAS are stored
VAR_ID_global_layer_key      = " "  // layer fuer key dimensions
VAR_ID_global_layer_make_up  = " "  // layer fuer sonstige dimensions und symbols
VAR_ID_global_layer_error    = " "  // layer fuer nicht mehr reevaluierbare Elemente
VAR_ID_global_layer_draw    = " "   // layer fuer Zeichnungsrahmen
VAR_ID_global_layer_draw_full = 0   // Wenn Zeichnungsrahmen schon vorhanden ist, nicht ueberschreiben
                                    //    0 = Es sind keine Elemente im Zeichnungsrahmen vorhanden
VAR_ID_global_layer_invis = " " // Alle unsichtbaren Elemente (Anwender moved Elemente in dieses Layer)


// Groups an associated with groups
// --------------------------------
                                // Mit I-DEAS-Attribut "nname"
VAR_ID_global_grp_point   = {}  //   Gruppe der vorhanden Punkte in der aktuellen view
  VAR_ID_global_grp_point_len = 0
  VAR_ID_global_grp_point_minniden = 0
  VAR_ID_global_grp_point_maxniden = 0
  VAR_ID_global_grp_point_nextniden = 0
  VAR_ID_global_grp_point_nextindex = 0
VAR_ID_global_grp_line    = {}  //   Gruppe der vorhanden Linien in der aktuellen view
  VAR_ID_global_grp_line_len = 0
  VAR_ID_global_grp_line_minniden = 0
  VAR_ID_global_grp_line_maxniden = 0
  VAR_ID_global_grp_line_nextniden = 0
  VAR_ID_global_grp_line_nextindex = 0
VAR_ID_global_grp_circle  = {}  //   Gruppe der vorhanden Kreis in der aktuellen view
  VAR_ID_global_grp_circle_len = 0
  VAR_ID_global_grp_circle_minniden = 0
  VAR_ID_global_grp_circle_maxniden = 0
  VAR_ID_global_grp_circle_nextniden = 0
  VAR_ID_global_grp_circle_nextindex = 0
VAR_ID_global_grp_ellips  = {}  //   Gruppe der vorhanden Ellipsen in der aktuellen view
  VAR_ID_global_grp_ellips_len = 0
  VAR_ID_global_grp_ellips_minniden = 0
  VAR_ID_global_grp_ellips_maxniden = 0
  VAR_ID_global_grp_ellips_nextniden = 0
  VAR_ID_global_grp_ellips_nextindex = 0
VAR_ID_global_grp_spline  = {}  //   Gruppe der vorhanden Splines in der aktuellen view
  VAR_ID_global_grp_spline_len = 0
  VAR_ID_global_grp_spline_minniden = 0
  VAR_ID_global_grp_spline_maxniden = 0
  VAR_ID_global_grp_spline_nextniden = 0
  VAR_ID_global_grp_spline_nextindex = 0
VAR_ID_global_grp_prims   = {}  //   Gruppe aller vorhanden Primitive in der aktuellen view
                                  // sortiert nach Identnummern
VAR_ID_global_grp_prims_len = 0 //   Laenge der Gruppe VAR_ID_global_grp_prims
VAR_ID_global_grp_ptshat  = {}  // Gruppe der erzeugten Punkte in der aktuellen view
                                //   die zum Erzeugen der Schraffur verwendet werden
VAR_ID_global_grp_world   = {}  // Alle Koordinatensysteme (worlds) mit I-DEAS IdentAttribut
VAR_ID_global_grp_mass    = {}  // Alle vorhandenen Masse
VAR_ID_global_grp_mass_len = 0  //   Laenge der Gruppe VAR_ID_global_grp_mass
VAR_ID_global_grp_plane = {}     // all planes
VAR_ID_global_grp_plane_len = 0  //   length of group VAR_ID_global_grp_plane
VAR_ID_global_grp_text = {}     // all text 
VAR_ID_global_grp_text_len = 0  //   length of group VAR_ID_global_grp_text
VAR_ID_global_grp_symbol = {}     // all symbol
VAR_ID_global_grp_symbol_len = 0  //   length of group VAR_ID_global_grp_symbol
VAR_ID_global_grp_invis   = {}  // Alle vorhandenen unsichtbaren Elemente innerhalb einer View
VAR_ID_global_grp_length  = {}  // all primitives 'length' with attribute 
//    "viewid" = -111 for measure height
//    "viewid" = -222 for text height
//    "viewid" = -333 for z values geometry and plane
//       names             objects                       default    AQL global name
//       "z_ideas_geo"     geometry                        0       VAR_ID_global_Z
//       "z_ideas_plane"   hatching planes                 0       VAR_ID_global_z_ideas_plane
//       "z_ideas_hide_plane"    hiding plane             -1000    VAR_ID_global_z_hide_plane
//       "z_ideas_detail_plane"  detail hatching planes   -1001    VAR_ID_global_z_detail_plane


// special for detail view with hatching plane
// -------------------------------------------
VAR_ID_global_grp_detailpoints = {} // all points describing view boundaries of detail views
VAR_ID_global_detailplane  = 0      // hiding plane for detail views
VAR_ID_global_detailboundary = 0    // external boundary of hiding plane
                                    // 0: first view --> create or edit the boundary
                                    // 1: other views --> do nothing
       // see in function ID_create_layer: length objects are created there
VAR_ID_global_Z              = 0      // default: z value of geometry objects
VAR_ID_global_z_ideas_plane  = 0      // default: z value of hatching planes
VAR_ID_global_z_hide_plane   = -1000  // default: z value of detail view hiding plane
VAR_ID_global_z_detail_plane = -1001  // default: z value of hatching planes
VAR_ID_global_detail_id_view0 = 0     // no special view identifier for all cover elememts
VAR_ID_global_detail_id_cover = -1000 // identifier for cover elements "hiding plane"
VAR_ID_global_detail_id_ptll  = -1001 // identifier for lower left boundary point
VAR_ID_global_detail_id_ptur  = -1002 // identifier for upper right boundary point
VAR_ID_global_detail_id_lines = -1003 // identifier for all detail view boundary lines 
VAR_ID_global_color_plane = ""        // default color = background color

// Attribute fuer I-DEAS Identifikatoren
// -------------------------------------
// "nview"   = Attributname fuer View-Identifikatoren
//             Integerwert kennzeichnet eine "nview"
// "nname"   = Attributname fuer View-Identifikatoren von Geometrieelementen
//             Alle Geometrieelemente einer View haben den gleichen Integerwert
// "niden"   = Attributname fuer Element-Identifikatoren von Geometrieelementen
//             point, line, circle, ellipse
//             Alle Geometrieelemente innerhalb einer View haben unterschiedliche,
//             eindeutige Integerwerte 
// "viewid"  = Attributname fuer View-Identifikatoren    von Massen, Texten und Symbolen
// "dimid"   = Attributname fuer Element-Identifikatoren von Massen
// "timid"   = attribut name for element identifier for text and symbols
//             detail view point boundary points and "cover plane"  
// "lname"   = Attributname fuer Layer-Identifikatoren des Modells
//             Alle Layer besitzen noch dieses Attribut mit den Layernamen als Wert
//             Beispiel: Layer test_1 hat .user_lname = "test_1"
        
// Sonstige globale Vereinbarungen
// -------------------------------
VAR_color_error_layer = 50     // Farbe fuer Error-Ebene
max_draw_dim = 1188.0          // Laenge/Breite DIN A0 Format
sqroot_2     = sqrt (2.0)      // Quadratwurzel aus 2 !
VAR_epsilon = 0.0005           // 0.033 fuer grosse Modelle
VAR_epsilon_schraffur = 0.005  // fuer Schraffur
VAR_epsilon1 = 0.1             // fuer DIN-Format  
VAR_ID_global_StringNil = ""   // Leerstring

VAR_ID_global_locked_layer = false // Sperren der erzeugten Layers
                            // true: gesperrt 
                            // false: nicht gesperrt

// Error messages in  "VAR_ID_global_error_file"
// ---------------------------------------------
// uniform file name from "login" und "process id"
VAR_ID_global_error_file = ID_TXT_Error + who() + string(program.pid)

// Information about part
// ----------------------
VAR_ID_global_PartNo = ""
VAR_ID_global_Ver    = ""
//VAR_ID_global_Rev    = ""

// ************************************************************
//                Funktionsdedeklaration forward
// ============================================================
function ID_after_dspline ( elem, id_view, id_prim ) forward
function ID_after_measure ( elem, itype, id_view, id_dim ) forward
function ID_after_symbol ( elem, id_view, id_prim ) forward
function ID_before_dspline(id_view, id_prim, nr_lines) forward
function ID_before_measure(itype, id_view, id_dim ) forward
function ID_before_symbol (id_view, id_prim) forward
function ID_before_text (id_view, id_prim) forward
function ID_cont_edit ( cont, grp_dx_dy, linestyle )  forward
function ID_create_arc(id_view, id_prim,elayer,str1,str2,p1,p2,p3) forward
function ID_create_arc_3p(id_view, id_prim,elayer,str1,str2,str3,p1,p2,p3) forward
function ID_create_balloon(id_view, id_prim, elayer,
         str1, p1, p2, ID_FONT, ID_ITALIC, ID_MODUS, height) forward
function ID_create_circle(id_view, id_prim,elayer,str1,str2,p1,r1) forward
function ID_create_color(str1, str2) forward
function ID_create_comment ( ID_FONT, ID_ITALIC, ID_MODUS, height, 
         arrowtyp, angle, str, p1, p2, p3, p4, id_view, id_prim ) forward
function ID_create_detail ( view_name, view_id, dxll, dyll, dxur, dyur ) forward
function ID_create_drawing() forward
function ID_create_ellipse(id_view, id_prim,elayer,str1,p1,r1, r2, r3) forward
function ID_create_ellipse_arc(id_view, id_prim,elayer,str1,p1, p2, p3, r1, r2, r3)  forward
function ID_cre_id_attr (elem,id_view,id_prim) forward
function ID_cre_id_attr_detail (elem,id_view,id_prim) forward
function ID_cre_id_attr_spline (elem,id_view,id_prim) forward
function ID_cre_id_attr_textsymbol (elem,itype,id_view,id_prim) forward
function ID_cre_id_attr_view ( elem, id_view) forward
function ID_create_layer(par_name) forward
function ID_create_line(id_view, id_prim,elayer,str1,str2,p1,p2) forward
function ID_create_plane ( id_view, id_prim,  elayer, cont, dist ,angle) forward
function ID_create_point(id_view, id_prim,dx,dy) forward
function ID_symbol_reference ( ID_FONT, ID_ITALIC, modus, height,
         val, start, bend, frame, id_view, id_prim ) forward
function ID_symbol_form ( ID_FONT, ID_ITALIC, modus, height,
         symb, val, gstring, start, bend, frame, id_view, id_prim) forward
function ID_create_section ( ID_FONT, ID_ITALIC, modus, height,
         grp1, str, p1, p2, id_view, id_prim ) forward
function ID_edit_section ( grp1, str ) forward
function ID_create_spline(id_view, id_prim, fname, 
         elayer, str1, iorder, grp) forward
function ID_create_text_height (hight) forward
function ID_create_texttext_height (hight) forward
function ID_create_posmeas_length ( str , d ) forward
function ID_create_coord_absolute ( dx, dy ) forward
function ID_create_view ( view_name, view_id, view_type, view_scale, dx, dy ) forward
function ID_create_world (par_name) forward
function ID_delete_ele(grp) forward
function ID_delete_cont(cont) forward
function ID_delete_elem(elem) forward
function ID_delete_view (id_view) forward
function ID_error_message ( faultnr, ele, id_view, id_prim ) forward
function ID_edit_text_block ( txtgrp ) forward
function ID_edit_comment ( str, p1 ) forward
function ID_edit_balloon( p, str ) forward
function ID_find_point_with_attr (id_prim) forward
function ID_find_line_with_attr (id_prim) forward
function ID_find_circle_with_attr (id_prim) forward
function ID_find_ellips_with_attr (id_prim) forward
function ID_find_meas_with_attr (id_view, id_prim) forward
function ID_find_spline_with_attr (id_prim, etyp) forward
function ID_find_plane_with_attr (id_view, id_prim) forward
function ID_find_text_with_attr (id_view, id_prim) forward
function ID_find_symbol_with_attr (id_view, id_prim) forward
function ID_find_world_with_attr (id_prim) forward
function ID_text_block ( ID_FONT, ID_ITALIC, ID_MODUS, height,
   textpos_enu, p1 , txtgrp, angle, id_view, id_prim ) forward
function ID_get_ID_Parameters() forward
function ID_get_create_layer ( lname, status) forward
function ID_header_set() forward
function ID_measure_angle2lines ( meas_old, id_view, id_prim, dtype, mtype,
   control, pretext, tol, comment,  ID_FONT, ID_ITALIC, ID_MODUS, height,
   anglelen, mtpos, l1, l2, sel, pos) forward
function ID_measure_chain ( meas_old, id_view, id_prim, dtype, 
   control, pretext, tol, comment,  ID_FONT, ID_ITALIC, ID_MODUS, height,
   pangle, mtpos, p1, p3, a, p2)  forward
function ID_measure_diamofcircle ( meas_old, id_view, id_prim, dtype,
   control, pretext, tol, comment,  ID_FONT, ID_ITALIC, ID_MODUS, height,
   mtpos, c, pangle, pos) forward
function ID_measure_plcplc ( meas_old, id_view, id_prim, dtype,
   control, pretext, tol, comment, ID_FONT, ID_ITALIC, ID_MODUS, height,
   pangle, el1, el2, pos)  forward
function ID_measure_radiusofsect ( meas_old, id_view, id_prim, dtype, mtype,
   control, pretext, tol, comment,  ID_FONT, ID_ITALIC, ID_MODUS, height,
   pangle, mtpos, c, pos) forward
function ID_model_start ( ) forward
function ID_move_to_layer (elem, itype, id_view ) forward
function ID_string_absolute (str) forward
function ID_transfer_end() forward
function ID_undo_delete ( ele )  forward
function ID_unit_set (iUnitCode, sUnitDesc, iTempMode, rLength, rForce, rTemp, rTempOff ) forward 
function get_first_30chars(fname) forward
function ID_hatch_loop() forward
function ID_get_model_file() forward
function ID_get_model_info() forward



// ************************************************************
//                Funktionsdefinitionen
// ============================================================


// ============================================================
function ID_unit_set (iUnitCode, sUnitDesc, iTempMode, rLength, rForce, rTemp, rTempOff ) 

   // Parameter:
   //   iUnitCode       /* Units code         */
   //   sUnitDesc       /* Units description  */
   //   iTempMode       /* Temperature mode   */
   //   rLength         /* Length             */
   //   rForce          /* Force              */
   //   rTemp           /* Temperature        */
   //   rTempOff        /* Temperature Offset */

  
   // set display of units to mm or inch
   // Einheiten in mm oder inch - Umrechnung erfolgt im ElementScaleFactor in design_ideas
   //   1 SI-Meter (newton)      meter   sec   kilogram(kg)       newton(N)  deg C:K
   //   2 BG-Foot (pound f)      foot    sec   lbf-sec**2/ft     pound(lbf)  deg F:R
   //   3 MG-Meter (kilogram f)  meter   sec   kgf-sec**2/m   kilogram(kgf)  deg C:K
   //   4 BA-Foot (poundal)      foot    sec   pound(lbm)      poundal(pdl)  deg F:R
   //   5 MM-mm (milli-newton)   mm      sec   kilogram(kg)    milli-newton  deg C:K
   //   6 CM-cm (centi-newton)   cm      sec   kilogram(kg)    centi-newton  deg C:K
   //   7 IN-Inch (pound f)      inch    sec   lbf-sec**2/in     pound(lbf)  deg F:R
   //   8 GM-mm (kilogram f)     mm      sec   kgf-sec**2/mm  kilogram(kgf)  deg C:K
   //   9 US-User defined        ____    sec   _____________  _____________  _____

   switch iUnitCode 
      case  2:  switch_units ( "inch" )
      case  4:  switch_units ( "inch" )
      case  7:  switch_units ( "inch" )
      otherwise: 
                switch_units ( "mm" )
   end
   return
end


// ============================================================

function ID_model_start ( )

   /* Grafik und Reevalueriung abschalten */

   if ID_DATE_OUTPUT then
      `model_start : ` [date()] nl 
   end


//   update_mode (false)
   prompt(ID_TXT_UpdateStart)

   // get information from file "idminfo.3d2d"
   ID_get_model_info()

   // Setup der Einleseprozedur
   if VAR_ID_global_name_ideas = " " then
      // Name fuer VAR_ID_global_world_ideas, VAR_ID_global_orig_ideas,
      //          VAR_ID_global_layer aus I-DEAS ableiten

      // max 'program.filenamesize' (28) characters
      if ( len(VAR_ID_global_cDrawName) > program.filenamesize) then
         VAR_ID_global_cDrawName = substr ( VAR_ID_global_cDrawName, 1, program.filenamesize)
         display_error(ID_TXT_CutNameLayer28Char + VAR_ID_global_cDrawName + "%")
      end
  
      VAR_ID_global_name_ideas = VAR_ID_global_cDrawName
   end

   // Get configuration parameters 
   ID_get_ID_Parameters()

   if VAR_ID_global_MFname != "" then
      VAR_ID_global_MFname = ID_simple_name (VAR_ID_global_MFname)
   end

   // add info of part to model_file name
//   VAR_ID_global_TopFname = VAR_ID_global_MFname + "_" + VAR_ID_global_PartNo +
//                                                   "_" + VAR_ID_global_Ver +
//                                                   "_" + VAR_ID_global_Rev

   VAR_ID_global_TopFname = VAR_ID_global_MFname + "_" +
                            VAR_ID_global_name_ideas

   // Fehlermeldungsausgabe nach Abfrage des Namens fuer Modelldatei
   file VAR_ID_global_error_file error_output

//   transfer_file   = getenv("IDEASGEO2")
   transfer_file   = "t"
   if valid(transfer_file) then
      // called directly from I-DEAS 
      ID_get_model_file()
   end

   ID_create_layer ( VAR_ID_global_name_ideas )
   ID_create_world ( VAR_ID_global_name_ideas )

   VAR_ID_global_grp_world  = VAR_ID_global_layer.list_world 
                              where valid(.user_nview)
end


// ============================================================

function get_first_30chars(fname)
  //  get the last 30 characters
  fstring = string_absolute (fname)
  result  = string_ofstring (fstring, 1, 30)
  return (result.s)
end

// ============================================================

function ID_create_drawing()

  // function: create Engineering Layout title block (= user )

  if VAR_ID_global_drawing = 1 and VAR_ID_global_layer_draw_full = 0 then
    if VAR_ID_global_dDrawVer > VAR_ID_global_dDrawHor    then
      //  Hochkantformat
      relev_dim = VAR_ID_global_dDrawVer
      relev_dimv = VAR_ID_global_dDrawHor
      //format_pos = ".port"    
      format_pos = "_port"    
    else
       relev_dim = VAR_ID_global_dDrawHor
       relev_dimv = VAR_ID_global_dDrawVer
       //format_pos = ".land"
       format_pos = "_land"
    end

    format_factor = max_draw_dim / relev_dim
    format_index  = 0
    while ( (format_factor - 1 ) > VAR_epsilon1 )   do
       format_factor = format_factor / sqroot_2
       format_index  = format_index + 1
    end 

    format_name = "a" + string(format_index) + format_pos
    pos = coord_onpoint(VAR_ID_global_orig_ideas)

    uda_name     = "#/symbols/" + format_name + ".uda"
    uda_name_top = "#/symbols/" + format_name + ".top"

    if ID_DEBUG then
       `format_name = ` [format_name] nl
       `uda_name = ` [uda_name] nl
       `uda_name_top = ` [uda_name_top] nl
    end

    if not existf (uda_name) then
       if existf (uda_name_top) then
          model_load (uda_name_top, false)
       else 
          `not found ` [uda_name_top] nl 
       end
    end
    if existf (uda_name) then
       uda_load (uda_name)
       switch format_name
          case "a0_land":   draw = a0_land ( pos, "", "", "", "", "" )
          case "a0_port":   draw = a0_port ( pos, "", "", "", "", "" )
          case "a1_land":   draw = a1_land ( pos, "", "", "", "", "" )
          case "a1_port":   draw = a1_port ( pos, "", "", "", "", "" )
          case "a2_land":   draw = a2_land ( pos, "", "", "", "", "" )
          case "a2_port":   draw = a2_port ( pos, "", "", "", "", "" )
          case "a3_land":   draw = a3_land ( pos, "", "", "", "", "" )
          case "a3_port":   draw = a3_port ( pos, "", "", "", "", "" )
          case "a4_land":   draw = a4_land ( pos, "", "", "", "", "" )
          case "a4_port":   draw = a4_port ( pos, "", "", "", "", "" )
          case "a5_land":   draw = a5_land ( pos )
          case "a5_port":   draw = a5_port ( pos )
          otherwise:   `please implement ID_create_drawing case ` [format_name] nl
               return
        end
   
      relev_dim_user = 0 
      switch format_index
        case 0:
             relev_dim_userh = 1188
             relev_dim_userv = 841
        case 1:
             relev_dim_userh = 841
             relev_dim_userv = 594
        case 2: 
             relev_dim_userh = 594
             relev_dim_userv = 420
        case 3: 
             relev_dim_userh = 420
             relev_dim_userv = 297
        case 4: 
             relev_dim_userh = 297
             relev_dim_userv = 210
        case 5: 
             relev_dim_userh = 210
             relev_dim_userv = 148
        otherwise: 
             relev_dim_userh = 0
             relev_dim_userv = 0
      end

      if ( relev_dim_userh -relev_dim > VAR_epsilon1 ) then
           // ID_TXT_Fault31 = "  horizontal: "
           // ID_TXT_Fault32 = " used instead of "
           // ID_TXT_Fault33 = "  vertical:   "
           if format_pos = ".land" then
              str1 = ID_TXT_Fault31 + string(relev_dim_userh) + ID_TXT_Fault32 + string(relev_dim)
              str2 = ID_TXT_Fault33 + string(relev_dim_userv) + ID_TXT_Fault32 + string(relev_dimv)
           else
              str1 = ID_TXT_Fault31 + string(relev_dim_userv) + ID_TXT_Fault32 + string(relev_dimv)
              str2 = ID_TXT_Fault33 + string(relev_dim_userh) + ID_TXT_Fault32 + string(relev_dim)
           end
           ID_error_message ( 3, str1, str2, 0 )
      end

      // Auf drawing Ebene schieben
      layer_move_objects ( {  draw }  , VAR_ID_global_layer_draw )
    else 
        `UDA not found ` [uda_name] nl
    end 
  end 
end
 
// ============================================================

function ID_create_world(par_name)
   // create first world for the whole layout
   // 
   // search world with name "par_name"
   // if doesn't exist, create them
   // Store world and reference point in global variables
   // world: VAR_ID_global_world_ideas
   // reference point: VAR_ID_global_orig_ideas 
   //    with name VAR_ID_global_name_ideas
   
   /* create origin, if not exist */
   /* --------------------------- */
   l = (top.list_point where .name = "origin")
   if empty(l) then
       p = point_origin (world_first ( {0, 0, 0}, 1))
       name (p, "origin")
   end
 
   /* Search for world with name "par_name" */
   /* ------------------------------------- */
   l = (top.list_world where .name = par_name)
   if empty(l) then 
      /* create world and get the origin of this world as reference point */
      wco = wcoord_absolute ( { 0, 0, 0 } ) 
      VAR_ID_global_world_ideas = world_firstrota ( wco, 0.0 , 1.0 )
      name (VAR_ID_global_world_ideas,  par_name)

      /* origin of world is reference point */
      VAR_ID_global_orig_ideas = VAR_ID_global_world_ideas.sons.first
      name (VAR_ID_global_orig_ideas, VAR_ID_global_name_ideas)
   else
      /* Keep world in "VAR_ID_global_world_ideas" and */
      /*      reference point = origin in "VAR_ID_global_orig_ideas" */
      VAR_ID_global_world_ideas = l.first
      VAR_ID_global_orig_ideas = VAR_ID_global_world_ideas.sons.first

      if VAR_ID_global_world_ideas.deleted then
         undo_delete(VAR_ID_global_world_ideas)
      end
   end
end

// ============================================================

function ID_create_view ( view_name, view_id, view_type, view_scale, dx, dy )
   // Parameter
   //   viewname:    string  "TOP", "FRONT", ...
   //   view_id:     int     1 , 2 , ... , 32
   //   view_type:   int     0, 1 , 2 , ... , 13
   //                        0 - Front View
   //                        1 - Top View
   //                        2 - Right Side View ...
   //                        7 - Detail View ...
   //                        13 - User Defined View
   //   view_scale:  double  scaling factor
   //   dx:          double  x-Koordinate des Ursprungs
   //   dy:          double  y-Koordinate des Ursprungs

   // Setzen des Namens der aktuellen View
   VAR_ID_global_name_view = view_name + "_" + VAR_ID_global_name_ideas

   // set view type to global variable 
   VAR_ID_global_type_view = view_type

   /* Erzeugen der World der einzelnen Ansichten */
   /* Namenslaenge darf nicht groesser als 30 Zeichen sein */
   if (len(VAR_ID_global_name_view) > 30) then
      // letzten 30 Zeichen verwenden
      VAR_ID_global_name_view = get_first_30chars(VAR_ID_global_name_view)        
   end

   /* Sucht eine world mit Namen "VAR_ID_global_name_view" */
   /* Wenn keine gefunden wurde, so wird eine erzeugt */
   /* World und deren Ursprung werden in globalen Variablen gemerkt */
   /* world: VAR_ID_global_world_view */
   /* Ursprung: VAR_ID_global_orig_view */


   /* Zeichnungsrahmen uebernehmen? */

   if (view_id = 32) then
      switch VAR_ID_global_drawing
         case 0: 
            /* Abruch der Prozedur, da Zeichnungsrahmen nicht */
            /*  uebergeben werden soll */
            ID_transfer_end() 
            return(-1)
         case 1: 
            /* use Engineering title block */
            /* abort the procedure         */
            ID_transfer_end() 
            return(-1)
         case 2: 
            if VAR_ID_global_layer_draw_full = 0 then
               edit (VAR_ID_global_layer_draw ,  , "active" , false  )
               // *** layer_set_active (VAR_ID_global_layer_draw)
            else
               ID_transfer_end() 
               return(-1)
            end            
         case 3: 
               edit (VAR_ID_global_layer_draw ,  , "active" , false  )
               // *** layer_set_active (VAR_ID_global_layer_draw)
         otherwise:
               ID_transfer_end() 
               return(-1)
       end
   end 
   
   prompt(ID_TXT_UpdateView + VAR_ID_global_name_view)

   l = (top.list_world where .name = VAR_ID_global_name_view)

   if empty(l) then 
      // Erzeugen des Referenzpunktes dieser world 
      //    relativ zu VAR_ID_global_orig_ideas
      pref = point_relative ( VAR_ID_global_orig_ideas, dx , dy)
      // Add attribut - necessary for deleting this point when
      // deleting the view; identifier = 0
      ID_cre_id_attr ( pref, view_id, 0 )

      // create world 
      wco = coord_onpoint (pref)
      VAR_ID_global_world_view = world_firstrota  (wco, 0.0, view_scale)
      name (VAR_ID_global_world_view,  VAR_ID_global_name_view)
      ID_cre_id_attr_view ( VAR_ID_global_world_view, view_id)  

      /* origin is reference point */
      VAR_ID_global_orig_view = VAR_ID_global_world_view.sons.first

      // Add attribut - necessary for deleting this point
      ID_cre_id_attr ( VAR_ID_global_orig_view, view_id, 0 )

      // Keine Primitive mit I-DEAS-Attributen vorhanden
      VAR_ID_global_grp_prims  = {} 
      VAR_ID_global_grp_point  = {} 
          VAR_ID_global_grp_point_len = 0
          VAR_ID_global_grp_point_minniden = 0
          VAR_ID_global_grp_point_maxniden = 0
          VAR_ID_global_grp_point_nextniden = 0
          VAR_ID_global_grp_point_nextindex = 0
      VAR_ID_global_grp_line   = {}
          VAR_ID_global_grp_line_len = 0
          VAR_ID_global_grp_line_minniden = 0
          VAR_ID_global_grp_line_maxniden = 0
          VAR_ID_global_grp_line_nextniden = 0
          VAR_ID_global_grp_line_nextindex = 0
      VAR_ID_global_grp_circle = {}
          VAR_ID_global_grp_circle_len = 0
          VAR_ID_global_grp_circle_minniden = 0
          VAR_ID_global_grp_circle_maxniden = 0
          VAR_ID_global_grp_circle_nextniden = 0
          VAR_ID_global_grp_circle_nextindex = 0
      VAR_ID_global_grp_ellips = {}
          VAR_ID_global_grp_ellips_len = 0
          VAR_ID_global_grp_ellips_minniden = 0
          VAR_ID_global_grp_ellips_maxniden = 0
          VAR_ID_global_grp_ellips_nextniden = 0
          VAR_ID_global_grp_ellips_nextindex = 0
      VAR_ID_global_grp_spline = {}
            VAR_ID_global_grp_spline_len = 0
            VAR_ID_global_grp_spline_minniden = 0
            VAR_ID_global_grp_spline_maxniden = 0
            VAR_ID_global_grp_spline_nextniden = 0
            VAR_ID_global_grp_spline_nextindex = 0
      VAR_ID_global_grp_invis  = {}
   else
      /* Store world in "VAR_ID_global_world_view" und */
      /*   reference point = origin in "VAR_ID_global_orig_view" */
      if len(l) > 1 then
         l1 = l where not .deleted
         if len(l1) > 0 then
            VAR_ID_global_world_view = l1.first 
         else
            VAR_ID_global_world_view = l.first 
         end
      else
         VAR_ID_global_world_view = l.first 
         if VAR_ID_global_world_view.deleted then
            undo_delete(VAR_ID_global_world_view)
         end
      end

      VAR_ID_global_orig_view = VAR_ID_global_world_view.sons.first

      // change position and scaling factor of world of view
      if VAR_ID_global_ViewModify = 0 then
          if VAR_ID_global_world_view.def_type = "onpoint" then // compatibility to VE 2.0
            /* Editieren des Punktes, wenn Values unterschiedlich sind */
            if abs(VAR_ID_global_world_view.par_p.par_dx.norm - dx) > VAR_epsilon then
               edit(VAR_ID_global_world_view.par_p.par_dx, dx)
            end 
            if abs(VAR_ID_global_world_view.par_p.par_dy.norm - dy) > VAR_epsilon then
               edit(VAR_ID_global_world_view.par_p.par_dy, dy)
            end 
            if abs(VAR_ID_global_world_view.par_s - view_scale) > VAR_epsilon then
               edit (VAR_ID_global_world_view, ,view_scale)
            end 
          else         
            /* Editieren des Punktes, wenn Values unterschiedlich sind */
            if abs(VAR_ID_global_world_view.par_pos.par_p.par_dx.norm - dx) > VAR_epsilon then
              edit(VAR_ID_global_world_view.par_pos.par_p.par_dx, dx)
            end 
            if abs(VAR_ID_global_world_view.par_pos.par_p.par_dy.norm - dy) > VAR_epsilon then
               edit(VAR_ID_global_world_view.par_pos.par_p.par_dy, dy)
            end 
            if abs(VAR_ID_global_world_view.par_s.norm - view_scale) > VAR_epsilon then
               edit (VAR_ID_global_world_view, , 0, view_scale)
            end 
         end
      end

      // Primitive mit I-DEAS-Attributen ermitteln
      // deleted entities are here
      grp_del = VAR_ID_global_layer_error.list_all where 
                                 .user_nname = view_id
      grp_del = grp_del + VAR_ID_global_layer_invis.list_all where 
                                 .user_nname = view_id and .deleted
      if len(grp_del) > 0 then
         VAR_ID_global_grp_prims  = ((VAR_ID_global_layer.list_all where 
                                     .user_nname = view_id) - grp_del)
                                     sort by .user_niden
      else
         VAR_ID_global_grp_prims  = (VAR_ID_global_layer.list_all where 
                                     .user_nname = view_id)
                                     sort by .user_niden
      end
 
      // entities also deleted ones: should exist only one time
      VAR_ID_global_grp_point  = VAR_ID_global_grp_prims where .prim_type = "point" 
        VAR_ID_global_grp_point_len = len(VAR_ID_global_grp_point)
        if VAR_ID_global_grp_point_len > 0 then
           VAR_ID_global_grp_point_minniden = VAR_ID_global_grp_point.first.user_niden
           VAR_ID_global_grp_point_maxniden = 
               VAR_ID_global_grp_point.["el_" + string(VAR_ID_global_grp_point_len)].user_niden
           VAR_ID_global_grp_point_nextindex = 1
           VAR_ID_global_grp_point_nextniden = VAR_ID_global_grp_point_minniden
        end
      VAR_ID_global_grp_line   = VAR_ID_global_grp_prims where .prim_type = "line"
        VAR_ID_global_grp_line_len = len(VAR_ID_global_grp_line)
        if VAR_ID_global_grp_line_len > 0 then
           VAR_ID_global_grp_line_minniden = VAR_ID_global_grp_line.first.user_niden
           VAR_ID_global_grp_line_maxniden = 
               VAR_ID_global_grp_line.["el_" + string(VAR_ID_global_grp_line_len)].user_niden
           VAR_ID_global_grp_line_nextindex = 1
              VAR_ID_global_grp_line_nextniden = VAR_ID_global_grp_line_minniden
        end
      VAR_ID_global_grp_circle = VAR_ID_global_grp_prims where .prim_type = "circle"
        VAR_ID_global_grp_circle_len = len(VAR_ID_global_grp_circle)
        if VAR_ID_global_grp_circle_len > 0 then
           VAR_ID_global_grp_circle_minniden = VAR_ID_global_grp_circle.first.user_niden
           VAR_ID_global_grp_circle_maxniden = 
               VAR_ID_global_grp_circle.["el_" + string(VAR_ID_global_grp_circle_len)].user_niden
           VAR_ID_global_grp_circle_nextindex = 1
           VAR_ID_global_grp_circle_nextniden = VAR_ID_global_grp_circle_minniden
        end
      VAR_ID_global_grp_ellips = VAR_ID_global_grp_prims where .prim_type = "ellips"
        VAR_ID_global_grp_ellips_len = len(VAR_ID_global_grp_ellips)
        if VAR_ID_global_grp_ellips_len > 0 then
           VAR_ID_global_grp_ellips_minniden = VAR_ID_global_grp_ellips.first.user_niden
           VAR_ID_global_grp_ellips_maxniden = 
               VAR_ID_global_grp_ellips.["el_" + string(VAR_ID_global_grp_ellips_len)].user_niden
           VAR_ID_global_grp_ellips_nextindex = 1
           VAR_ID_global_grp_ellips_nextniden = VAR_ID_global_grp_ellips_minniden
        end
      VAR_ID_global_grp_spline = VAR_ID_global_grp_prims where  valid(.user_nspline)
        VAR_ID_global_grp_spline_len = len(VAR_ID_global_grp_spline)
        if VAR_ID_global_grp_spline_len > 0 then
           VAR_ID_global_grp_spline_minniden = VAR_ID_global_grp_spline.first.user_nspline
           VAR_ID_global_grp_spline_maxniden = 
               VAR_ID_global_grp_spline.["el_" + string(VAR_ID_global_grp_spline_len)].user_nspline
           VAR_ID_global_grp_spline_nextindex = 1
           VAR_ID_global_grp_spline_nextniden = VAR_ID_global_grp_spline_minniden
        end
        VAR_ID_global_grp_invis  = VAR_ID_global_layer_invis.list_all
                                                where .user_nname = view_id
   end

   // Anzahl der Primitive in der aktuellen View
   VAR_ID_global_grp_prims_len  = len(VAR_ID_global_grp_prims) 

   if ( ID_DEBUG ) then 
      `View: ` [view_name] ` ` [view_id] ` ` [view_type] nl
      `  VAR_ID_global_grp_prims_len  = ` [VAR_ID_global_grp_prims_len] nl 
      `  VAR_ID_global_grp_point_len  = ` [VAR_ID_global_grp_point_len] nl 
      `  VAR_ID_global_grp_line_len   = ` [VAR_ID_global_grp_line_len] nl 
      `  VAR_ID_global_grp_circle_len = ` [VAR_ID_global_grp_circle_len] nl 
      `  VAR_ID_global_grp_ellips_len = ` [VAR_ID_global_grp_ellips_len] nl 
      `  VAR_ID_global_grp_spline_len = ` [VAR_ID_global_grp_spline_len] nl 
   end

end

// ============================================================

function ID_create_detail ( view_name, view_id, 
                            dxll, dyll, dxur, dyur )
  // input
  //   view_name: string  "TOP", "FRONT", ...
  //   view_id:   int     1 , 2 , ... , 32
  //   dxll:      double  x value of lower left view boundary point
  //   dyll:      double  y value of lower left view boundary point
  //   dxur:      double  x value of upper right view boundary point
  //   dyur:      double  y value of upper right view boundary point
  //
  // return: -
  // 
  // description:
  // - Create/Edit a plane ("hiding plane = Ausblendflaeche") in order
  //   to hide hatching planes in detail views.
  // - Every detail view have the same external boundary
  // - The hiding plane consists of 4 external and for each detail view
  //   4 internal lines.
  //
  ptll = 0         // lower left view boundary point
  ptur = 0         //upper right view boundary point
  view_plane = 0   // hiding plane for this view
  grp_alines = {}  // all lines of view boundary
  grp_elines = {}  // external lines of view boundary
                   //   paper size lines (4) used to
                   //   describe external view boundary 
  grp_ilines = {}  // internal lines of view boundary of actual detail view

  // create/edit external boundary of the "hiding plane"
  // ------------------------------------------------------

  if VAR_ID_global_detailboundary = 0 then

     VAR_ID_global_detailboundary = 1

     dsxll = -VAR_ID_global_dDrawHor/2  // defaults
     dsyll = -VAR_ID_global_dDrawVer/2
     dsxur = VAR_ID_global_dDrawHor*1.5
     dsyur = VAR_ID_global_dDrawVer*1.5

     // search for lower left and upper right point
     grp_points = VAR_ID_global_grp_detailpoints 
          where .user_viewid = VAR_ID_global_detail_id_view0

     if len(grp_points) = 2 then
        ptll = grp_points.first
        if ptll.user_detail = VAR_ID_global_detail_id_ptll then
           ptur = grp_points.el_2
        else
           ptur = ptll
           VAR_ID_global_detail_id_ptll = grp_points.el_2
        end

        // don't edit - let it be!
        // edit lower left if smaller
        // if dsxll < ptll.par_dx.norm then
        //    edit(ptll.par_dx, dsxll)
        // end 
        // if dsyll < ptll.par_dy.norm then
        //    edit(ptll.par_dy, dsyll)
        // end 
        // edit upper right point if bigger
        // if dsxur > ptur.par_dx.norm  then
        //    edit(ptur.par_dx, dsxur)
        // end 
        // if dsyur > ptur.par_dy.norm then
        //    edit(ptur.par_dy, dsyur)
        // end 

        // search the 4 external boundary line
        grp_elines = (ptll.sons where .prim_type = "line" 
                      and .user_viewid = VAR_ID_global_detail_id_view0) 
                   + (ptur.sons where .prim_type = "line" 
                      and .user_viewid = VAR_ID_global_detail_id_view0)
    else
        // create lower left and upper right point
        ptll = point_relative(VAR_ID_global_orig_ideas, dsxll, dsyll)
        name(ptll, VAR_ID_global_cDrawName + "_lower_left")
        ptur = point_relative(VAR_ID_global_orig_ideas, dsxur, dsyur)
        name(ptur, VAR_ID_global_cDrawName + "_upper_right")

        // attach attribute to point and move it to layer
        ID_cre_id_attr_detail (ptll, VAR_ID_global_detail_id_view0, 
                                     VAR_ID_global_detail_id_ptll)
        ID_cre_id_attr_detail (ptur, VAR_ID_global_detail_id_view0, 
                                     VAR_ID_global_detail_id_ptur)
     end

     if len(grp_elines) != 4 then
        p1 =  point_relativex1y2 ( ptll, ptur )
        p2 =  point_relativex1y2 ( ptur , ptll )
        l1 =  line_pointpoint (  , { "solid", 3 } , "is_limited" , ptll , p1 )
        l2 =  line_pointpoint (  , { "solid", 3 } , "is_limited" , p1 , ptur )
        l3 =  line_pointpoint (  , { "solid", 3 } , "is_limited" , ptur , p2 )
        l4 =  line_pointpoint (  , { "solid", 3 } , "is_limited" , p2 ,  ptll )
        grp_elines = { l1, l2, l3, l4 }

        // attach attribute to lines and move it to layer
        ID_cre_id_attr_detail (l1, VAR_ID_global_detail_id_view0,
                                   VAR_ID_global_detail_id_cover)    
        ID_cre_id_attr_detail (l2, VAR_ID_global_detail_id_view0,
                                   VAR_ID_global_detail_id_cover)    
        ID_cre_id_attr_detail (l3, VAR_ID_global_detail_id_view0,
                                   VAR_ID_global_detail_id_cover)    
        ID_cre_id_attr_detail (l4, VAR_ID_global_detail_id_view0,
                                   VAR_ID_global_detail_id_cover) 
        delete(grp_elines)
        delete ( { p1, p2 } )

     end

     if VAR_ID_global_detailplane != 0 then
        // search for the external boundary lines in plane
        if not (grp_elines.first in VAR_ID_global_detailplane.par_poe) then
          // remove old lines and add new lines
          grp_old_lines = VAR_ID_global_detailplane.par_poe 
                      where .user_viewid = VAR_ID_global_detail_id_view0
          grp_alines = VAR_ID_global_detailplane.par_poe 
                       - grp_old_lines + grp_elines 
          edit(VAR_ID_global_detailplane, , , , grp_alines, , )
        end      
     end      
  end

  // - search the internal view boundary points and edit its values or create them
  grp_points = VAR_ID_global_grp_detailpoints where .user_viewid = view_id 
  if len(grp_points) = 2 then
     ptll = grp_points.first
     if ptll.user_detail = VAR_ID_global_detail_id_ptll then
        ptur = grp_points.el_2
     else
        ptur = ptll
        VAR_ID_global_detail_id_ptll = grp_points.el_2
     end
     // edit values of boundary points

     dx = dxll + VAR_ID_global_world_view.par_pos.par_p.par_dx.norm
     if abs(ptll.par_dx.norm - dx) > VAR_epsilon then
        edit(ptll.par_dx, dx)
     end
     dy = dyll + VAR_ID_global_world_view.par_pos.par_p.par_dy.norm
     if abs(ptll.par_dy.norm - dy) > VAR_epsilon then
        edit(ptll.par_dy, dy)
     end 
     dx = dxur + VAR_ID_global_world_view.par_pos.par_p.par_dx.norm
     if abs(ptur.par_dx.norm - dx) > VAR_epsilon then
        edit(ptur.par_dx, dx)
     end 
     dy = dyur + VAR_ID_global_world_view.par_pos.par_p.par_dy.norm
     if abs(ptur.par_dy.norm - dy) > VAR_epsilon then
        edit(ptur.par_dy, dy)
     end  
     // search the lines of view boundary
     grp_ilines = (ptll.sons where .prim_type = "line" and .user_viewid = view_id) 
                + (ptur.sons where .prim_type = "line" and .user_viewid = view_id)
  else
     // points are created relative to VAR_ID_global_orig_ideas
     // because: the elements of the plane should belong to the same world
     //          (= same scaling factor)
     dx = dxll + VAR_ID_global_world_view.par_pos.par_p.par_dx.norm
     dy = dyll + VAR_ID_global_world_view.par_pos.par_p.par_dy.norm
     ptll = point_relative(VAR_ID_global_orig_ideas,dx,dy)
     dx = dxur + VAR_ID_global_world_view.par_pos.par_p.par_dx.norm
     dy = dyur + VAR_ID_global_world_view.par_pos.par_p.par_dy.norm
     ptur = point_relative(VAR_ID_global_orig_ideas,dx,dy)

     // attach attribute to points and move it to layer
     ID_cre_id_attr_detail (ptll,view_id,VAR_ID_global_detail_id_ptll)     
     ID_cre_id_attr_detail (ptur,view_id,VAR_ID_global_detail_id_ptur)
     delete ( { ptll, ptur } )
  end


  if len(grp_ilines) != 4 then
     // create the lines of internal boundary lines
     p1 =  point_relativex1y2 ( ptll , ptur )
     p2 =  point_relativex1y2 ( ptur , ptll )
     l1 =  line_pointpoint (   , { "solid", 3 } , "is_limited" , ptll , p1 )
     l2 =  line_pointpoint (   , { "solid", 3 } , "is_limited" , p1 , ptur )
     l3 =  line_pointpoint (   , { "solid", 3 } , "is_limited" , ptur , p2 )
     l4 =  line_pointpoint (   , { "solid", 3 } , "is_limited" , p2 , ptll )

     // attach attribute to lines and move it to layer
     ID_cre_id_attr_detail (l1, view_id, VAR_ID_global_detail_id_lines)     
     ID_cre_id_attr_detail (l2, view_id, VAR_ID_global_detail_id_lines)     
     ID_cre_id_attr_detail (l3, view_id, VAR_ID_global_detail_id_lines)     
     ID_cre_id_attr_detail (l4, view_id, VAR_ID_global_detail_id_lines) 

     grp_ilines = { l1, l2, l3, l4 }
     delete ( { p1, p2} )
     delete ( grp_ilines )
  end

  //  create or edit the hiding plane
  if VAR_ID_global_detailplane != 0 then
     // there can exist old internal lines which must be removed

     grp_old_lines = VAR_ID_global_detailplane.par_poe 
                     where .user_viewid = view_id
     if grp_ilines.first in grp_old_lines or len(grp_old_lines) = 0 then
        // old lines == new lines
        if not (grp_ilines.first in VAR_ID_global_detailplane.par_poe) then
           grp_alines = VAR_ID_global_detailplane.par_poe + grp_ilines
           edit(VAR_ID_global_detailplane, , , , grp_alines, , )
        end
     else
        // remove old lines and add new lines
        grp_alines = VAR_ID_global_detailplane.par_poe 
                     - grp_old_lines + grp_ilines 
        edit(VAR_ID_global_detailplane, , , , grp_alines, , )
     end      
  else
     // create the hiding plane
     grp_alines = grp_elines + grp_ilines
     VAR_ID_global_detailplane = plane_ofelements 
         ( VAR_ID_global_z_hide_plane, VAR_ID_global_color_plane,
           {"hatch_no",true}, grp_alines, 3, 45)

     // attach attributes and move to layer
     ID_cre_id_attr_detail (VAR_ID_global_detailplane,
                            VAR_ID_global_detail_id_view0, 
                            VAR_ID_global_detail_id_cover)
  end


end 

// ============================================================

function ID_create_layer(par_name)

   /* set top layer activ */
   if top.status != "active" then
     edit (  top , ,"visible", false)
     edit (  top , ,"active" , false)
   end

   /* search or edit main layer for drawing and the sublayers */
   VAR_ID_global_layer     = ID_get_create_layer ( par_name  , "active" )
   VAR_ID_global_layer_key     = ID_get_create_layer ( par_name + "_key"     , "selectable" )
   VAR_ID_global_layer_make_up = ID_get_create_layer ( par_name + "_make_up" , "selectable" )
   VAR_ID_global_layer_draw    = ID_get_create_layer ( par_name + "_draw"    , "selectable" )
   VAR_ID_global_layer_error   = ID_get_create_layer ( par_name + "_error"   , "selectable" )
   VAR_ID_global_layer_invis   = ID_get_create_layer ( par_name + "_invis"   , "inactive" )

   // get all primitives length with attribute (used in dimension height)
   VAR_ID_global_grp_length = VAR_ID_global_layer.list_length where valid (.user_viewid) and
                          .user_viewid <= -111

   // search or create z_lengths for planes (user attribute "viewid" = -333)
   //     name          object                 default z-value  global name
   // "z_ideas_geo"     geometry                        0       VAR_ID_global_Z
   // "z_ideas_plane"   hatching planes                 0       VAR_ID_global_z_ideas_plane
   // "z_ideas_hide_plane"    hiding plane             -1000    VAR_ID_global_z_hide_plane
   // "z_ideas_detail_plane"  detail hatching planes   -1001    VAR_ID_global_z_detail_plane
 
   z_grp_length = top.list_length where valid (.user_viewid) and .user_viewid = -333

   res = z_grp_length where .name = "z_ideas_geo"
   if empty(res) then
      VAR_ID_global_Z = length_absolute(0)
      name (VAR_ID_global_Z, "z_ideas_geo")
      ID_creatt_user_attrib (VAR_ID_global_Z, "viewid", -333 )
   else
      VAR_ID_global_Z = res.first
   end 

   res = z_grp_length where .name = "z_ideas_plane"
   if empty(res) then
      VAR_ID_global_z_ideas_plane = length_absolute(0)
      name (VAR_ID_global_z_ideas_plane, "z_ideas_plane")
      ID_creatt_user_attrib (VAR_ID_global_z_ideas_plane, "viewid", -333 )
   else
       VAR_ID_global_z_ideas_plane = res.first
   end 

   res = z_grp_length where .name = "z_ideas_hide_plane"
   if empty(res) then
       VAR_ID_global_z_hide_plane = length_absolute(-1000)
      name (VAR_ID_global_z_hide_plane, "z_ideas_hide_plane")
      ID_creatt_user_attrib (VAR_ID_global_z_hide_plane, "viewid", -333 )
   else
      VAR_ID_global_z_hide_plane = res.first
   end 

   res = z_grp_length where .name = "z_ideas_detail_plane"
   if empty(res) then
      VAR_ID_global_z_detail_plane = length_absolute(-1001)
      name (VAR_ID_global_z_detail_plane, "z_ideas_detail_plane")
      ID_creatt_user_attrib (VAR_ID_global_z_detail_plane, "viewid", -333 )
   else
      VAR_ID_global_z_detail_plane = res.first
   end 
 
   // get all old transferred elements from layer "_key"
   VAR_ID_global_grp_mass = VAR_ID_global_layer_key.list_measure
                      where valid(.user_dimid) and not .deleted

   // get all old transferred elements from layer "_make_up"
   VAR_ID_global_grp_mass = ( VAR_ID_global_layer_make_up.list_measure
               where valid(.user_dimid) and not .deleted )
                 +  VAR_ID_global_grp_mass

   // search for all transferred texts, symbols, planes
   grp_textsymbol = VAR_ID_global_layer_make_up.list_all
                     where valid(.user_timid) and not .deleted
   VAR_ID_global_grp_plane = grp_textsymbol
                        where .prim_type = "plane"
   VAR_ID_global_grp_text = grp_textsymbol
                        where .prim_type = "text"
   VAR_ID_global_grp_symbol =  grp_textsymbol
                        where .prim_type = "symbol"

   // search all view boundary points for detail views
   VAR_ID_global_grp_detailpoints = VAR_ID_global_layer_make_up.list_point 
            where valid(.user_detail)
   // search the hiding plane used for detail views
   grp_planes = VAR_ID_global_layer_make_up.list_plane 
         where .user_detail =  VAR_ID_global_detail_id_cover
         and not .deleted
   if len(grp_planes) = 1 then
      VAR_ID_global_detailplane = grp_planes.first
   end

   // get all old transferred elements from layer "_draw"
   grp = VAR_ID_global_layer_draw.list_all where not .deleted 
   if len(grp) > 1 then  // one point is created
      // Wenn Elemente im layer vorhanden sind,
      //   nicht ueberschreiben
      VAR_ID_global_layer_draw_full = 1
      if VAR_ID_global_drawing = 3 then
      // delete all primitives to create them new
            grp_del = grp where valid(.user_viewid) // or valid(.user_nname)
            delete( grp_del)
      end
   end 

      // layer selektierbar machen, Sperrung aufheben und alle Elemente loeschen
      edit ( VAR_ID_global_layer_key ,  ,"selectable" , false)

   // get all old transferred elements from layer "_invis"
   grp = ( VAR_ID_global_layer_invis.list_measure
                     where valid (.user_dimid) and not .deleted )
   VAR_ID_global_grp_mass = grp + VAR_ID_global_grp_mass

   // Ermitteln aller alten uebertragenen Texte und Symbole
   grp = ( VAR_ID_global_layer_invis.list_all
                  where valid (.user_timid) and not .deleted )
   grp_plane = grp where .prim_type = "plane"
   VAR_ID_global_grp_plane = grp_plane + VAR_ID_global_grp_plane
   grp_text = grp where .prim_type = "text"
   VAR_ID_global_grp_text = grp_text + VAR_ID_global_grp_text
   grp_symbol = grp where .prim_type = "symbol"
   VAR_ID_global_grp_symbol = grp_symbol + VAR_ID_global_grp_symbol

   // get the length of groups
   VAR_ID_global_grp_mass_len = len(VAR_ID_global_grp_mass)

   VAR_ID_global_grp_plane_len = len(VAR_ID_global_grp_plane) 
   VAR_ID_global_grp_text_len = len(VAR_ID_global_grp_text) 
   VAR_ID_global_grp_symbol_len = len(VAR_ID_global_grp_symbol) 
   if VAR_ID_global_TextModify = 0 then
     delete(VAR_ID_global_grp_text)
   end
   if VAR_ID_global_SymbolModify = 0 then
     delete(VAR_ID_global_grp_plane)
     delete(VAR_ID_global_grp_symbol)
   end

end

// ============================================================

function ID_delete_view (id_view)
// input: id_view   int ... view identifier
// function: delete all elements belonging to the view 


   ele =  ID_find_world_with_attr (id_view)
   if ( ele != 0 ) then
      delete(ele)
      if valid (ele.par_pos) then
         delete(ele.par_pos)
      end

      del_grp = VAR_ID_global_layer.list_all 
                   where .user_nname = id_view or
                         .user_viewid = id_view
                   and not .deleted
      // search four contours = dsplines
      del_cont = del_grp where valid (.user_nspline) 
                       and .prim_type = "contour"
      for ele in del_cont do
          ID_delete_cont(ele)
      end
      del_grp = del_grp - del_cont
      if not empty(del_grp) then
         grp_effects = {}
         for ele in del_grp do 
            grp_err = ele.sons where not valid(.user_nname)
            if not empty(grp_err) then
               layer_move_objects ( grp_err , VAR_ID_global_layer_error)
            end
            if ( len(ele.created_by.list_effects) > 0 ) then
               grp_effects = grp_effects + ele.created_by.list_effects
            end
         end
         layer_move_objects ( del_grp , VAR_ID_global_layer_error)
         delete(del_grp)
         delete (grp_effects)  // effects must also be deleted 
      end

      // search for detail view elements
      if VAR_ID_global_detailplane != 0 then
         grp_detaillines = VAR_ID_global_layer_make_up.list_line
                           where .user_detail = VAR_ID_global_detail_id_lines
                           and   .user_viewid = id_view
        if len(grp_detaillines) > 0 then
           // eliminate lines of deleted detail view from hiding plane
           gruppe = VAR_ID_global_detailplane.par_poe - grp_detaillines
           edit ( VAR_ID_global_detailplane ,  ,  ,  , gruppe, , )
        end

        grp_points = VAR_ID_global_grp_detailpoints where 
                           where .user_viewid = id_view
        VAR_ID_global_grp_detailpoints = VAR_ID_global_grp_detailpoints - grp_points
      end
   end 
end


// ============================================================

function ID_delete_ele(grp)
   // delete the group with attributes "id_prim" within the actual view
   // and move them to the error layer
   // sons without I-DEAS Identifikator --> VAR_ID_global_layer_error
   //    grp_err =  group of sons --> error
 
   if (VAR_ID_global_grp_prims_len >  0) then
      del_grp = VAR_ID_global_grp_prims where .user_niden in grp
      if not empty(del_grp) then
         grp_effects = {}
         for ele in del_grp do 
            grp_err = ele.sons where not valid(.user_nname)
            if not empty(grp_err) then
               layer_move_objects ( grp_err , VAR_ID_global_layer_error)
            end
            if ( len(ele.created_by.list_effects) > 0 ) then
               grp_effects = grp_effects + ele.created_by.list_effects
            end
         end
         layer_move_objects ( del_grp , VAR_ID_global_layer_error)
         delete(del_grp)       // delete after move
         delete (grp_effects)  // effects must also be deleted 
      end
      // delete lines of dspline
      del_dspline = del_grp where .prim_type = "contour"
      for i in del_dspline do
         for j in i.par_coe do
            grp_err = j.sons where not valid(.user_nname)
            if not empty(grp_err) then
               layer_move_objects ( grp_err , VAR_ID_global_layer_error)
            end              
         end
      end
   end
end

// ============================================================

function ID_delete_elem(del_elem)
// function: delete element (primitive) or group of elements
// delete primitive
//     sons without I-DEAS Identifikator
//     move them to the error layer--> VAR_ID_global_layer_error
// delete group
//     sons without I-DEAS Identifikator which are not in group
//     move them to the error layer--> VAR_ID_global_layer_error
 
   if valid (del_elem.prim_type) then
      grp_err = del_elem.sons where not valid(.user_nname)
      if not empty(grp_err) then
         layer_move_objects ( grp_err , VAR_ID_global_layer_error)
      end
      layer_move_objects ( { del_elem } , VAR_ID_global_layer_error)
      delete(del_elem)
      if ( len(del_elem.created_by.list_effects) > 0 ) then
           // effects must also be deleted 
           delete (del_elem.created_by.list_effects)  
      end
  else
      for ele in del_elem do 
         grp_err = ele.sons where not valid(.user_nname)
         if not empty(grp_err) then
            layer_move_objects ( grp_err , VAR_ID_global_layer_error)
         end
      end
      layer_move_objects ( del_elem , VAR_ID_global_layer_error)
      delete(del_elem)
   end
end

// ============================================================

function ID_delete_cont(cont)
// function: delete countour and its lines
 
   layer_move_objects ( { cont } , VAR_ID_global_layer_error)
   layer_move_objects ( cont.par_coe , VAR_ID_global_layer_error)
   delete(cont)
   delete(cont.par_coe)
end

// ============================================================

function ID_create_color(str1, str2)
     /* keine Veraenderung der Farbe des Elementes */
end

// ===================================================================

function ID_find_point_with_attr (id_prim)
   // Suchen eines Punktes
   //    mit Identifikator "id_prim" in der Elementliste der aktuellen View
   // return 0, wenn nicht gefunden

   elem = 0 

   if VAR_ID_global_grp_point_len > 0 then
    if (id_prim >= VAR_ID_global_grp_point_minniden and 
       id_prim <= VAR_ID_global_grp_point_maxniden ) then
      work = "work"
      what = "exit"

      if VAR_ID_global_grp_point_nextniden = id_prim then
         what = "found"
      else if VAR_ID_global_grp_point_nextniden < id_prim then
         what = "search"
      else
         what = "reset_search"
      end
      end
    end

    while work = "work" do
     switch what
       case "search":
         while ( VAR_ID_global_grp_point_nextindex < VAR_ID_global_grp_point_len and
                 what = "search" ) do
            VAR_ID_global_grp_point_nextindex = VAR_ID_global_grp_point_nextindex + 1   
            VAR_ID_global_grp_point_nextniden = VAR_ID_global_grp_point.["el_" 
                      + string(VAR_ID_global_grp_point_nextindex)].user_niden 
            if VAR_ID_global_grp_point_nextniden = id_prim then
               what = "found"
            else if VAR_ID_global_grp_point_nextniden > id_prim then
               what = "exit"
            end
            end
          end
          if what = "search" then
             what = "stop"
          end
       case "found":
          elem = VAR_ID_global_grp_point.["el_" + string(VAR_ID_global_grp_point_nextindex)]
          VAR_ID_global_grp_point = VAR_ID_global_grp_point - elem
          VAR_ID_global_grp_point_len = VAR_ID_global_grp_point_len - 1
          if ( VAR_ID_global_grp_point_nextindex <= VAR_ID_global_grp_point_len ) then
            VAR_ID_global_grp_point_nextniden = VAR_ID_global_grp_point.["el_" + 
                      string(VAR_ID_global_grp_point_nextindex)].user_niden
          else
            // reset to first element
            VAR_ID_global_grp_point_nextindex = 1
            VAR_ID_global_grp_point_nextniden = VAR_ID_global_grp_point_minniden 
          end
          work = "end"
       case "stop":
          if ( VAR_ID_global_grp_point_nextindex < VAR_ID_global_grp_point_len ) then
            VAR_ID_global_grp_point_nextindex = VAR_ID_global_grp_point_nextindex + 1
            VAR_ID_global_grp_point_nextniden = VAR_ID_global_grp_point.["el_" + 
                      string(VAR_ID_global_grp_point_nextindex)].user_niden
          else
            // reset to first element
            VAR_ID_global_grp_point_nextindex = 1
            VAR_ID_global_grp_point_nextniden = VAR_ID_global_grp_point_minniden 
          end
          work = "end"
       case "reset_search":
          // reset to first element
          VAR_ID_global_grp_point_nextindex = 1
          VAR_ID_global_grp_point_nextniden = VAR_ID_global_grp_point_minniden 
          what = "search"
       case "exit":
          work = "end"
     end
    end           
   end           
   return (elem)

end

// ===================================================================

function ID_find_line_with_attr (id_prim)
   // Suchen einer Linie
   //    mit Identifikator "id_prim" in der Elementliste der aktuellen View
   // return 0, wenn nicht gefunden

   elem = 0 

   if VAR_ID_global_grp_line_len > 0 then
    
    if (id_prim >= VAR_ID_global_grp_line_minniden and 
       id_prim <= VAR_ID_global_grp_line_maxniden ) then
      work = "work"
      what = "exit"

      if VAR_ID_global_grp_line_nextniden = id_prim then
         what = "found"
      else if VAR_ID_global_grp_line_nextniden < id_prim then
         what = "search"
      else
         what = "reset_search"
      end
      end
    end

    while work = "work" do
     switch what
       case "search":
         while ( VAR_ID_global_grp_line_nextindex < VAR_ID_global_grp_line_len and
                 what = "search" ) do
            VAR_ID_global_grp_line_nextindex = VAR_ID_global_grp_line_nextindex + 1   
            VAR_ID_global_grp_line_nextniden = VAR_ID_global_grp_line.["el_" 
                      + string(VAR_ID_global_grp_line_nextindex)].user_niden 
            if VAR_ID_global_grp_line_nextniden = id_prim then
               what = "found"
            else if VAR_ID_global_grp_line_nextniden > id_prim then
               what = "exit"
            end
            end
          end
          if what = "search" then
             what = "stop"
          end
       case "found":
          elem = VAR_ID_global_grp_line.["el_" + string(VAR_ID_global_grp_line_nextindex)]
          VAR_ID_global_grp_line = VAR_ID_global_grp_line - elem
          VAR_ID_global_grp_line_len = VAR_ID_global_grp_line_len - 1
          if ( VAR_ID_global_grp_line_nextindex <= VAR_ID_global_grp_line_len ) then
            VAR_ID_global_grp_line_nextniden = VAR_ID_global_grp_line.["el_" + 
                      string(VAR_ID_global_grp_line_nextindex)].user_niden
          else
            // reset to first element
            VAR_ID_global_grp_line_nextindex = 1
            VAR_ID_global_grp_line_nextniden = VAR_ID_global_grp_line_minniden 
          end
          work = "end"
       case "stop":
          if ( VAR_ID_global_grp_line_nextindex < VAR_ID_global_grp_line_len ) then
            VAR_ID_global_grp_line_nextindex = VAR_ID_global_grp_line_nextindex + 1
            VAR_ID_global_grp_line_nextniden = VAR_ID_global_grp_line.["el_" + 
                      string(VAR_ID_global_grp_line_nextindex)].user_niden
          else
            // reset to first element
            VAR_ID_global_grp_line_nextindex = 1
            VAR_ID_global_grp_line_nextniden = VAR_ID_global_grp_line_minniden 
          end
          work = "end"
       case "reset_search":
          // reset to first element
          VAR_ID_global_grp_line_nextindex = 1
          VAR_ID_global_grp_line_nextniden = VAR_ID_global_grp_line_minniden 
          what = "search"
       case "exit":
          work = "end"
     end
    end           
   end           
   return (elem)

end


// ===================================================================

function ID_find_circle_with_attr (id_prim)
   // Suchen eines Kreises
   //    mit Identifikator "id_prim" in der Elementliste der aktuellen View
   // return 0, wenn nicht gefunden

   elem = 0 

   if VAR_ID_global_grp_circle_len > 0 then
    if (id_prim >= VAR_ID_global_grp_circle_minniden and 
       id_prim <= VAR_ID_global_grp_circle_maxniden ) then
      work = "work"
      what = "exit"

      if VAR_ID_global_grp_circle_nextniden = id_prim then
         what = "found"
      else if VAR_ID_global_grp_circle_nextniden < id_prim then
         what = "search"
      else
         what = "reset_search"
      end
      end
    end

    while work = "work" do
     switch what
       case "search":
         while ( VAR_ID_global_grp_circle_nextindex < VAR_ID_global_grp_circle_len and
                 what = "search" ) do
            VAR_ID_global_grp_circle_nextindex = VAR_ID_global_grp_circle_nextindex + 1   
            VAR_ID_global_grp_circle_nextniden = VAR_ID_global_grp_circle.["el_" 
                      + string(VAR_ID_global_grp_circle_nextindex)].user_niden 
            if VAR_ID_global_grp_circle_nextniden = id_prim then
               what = "found"
            else if VAR_ID_global_grp_circle_nextniden > id_prim then
               what = "exit"
            end
            end
          end
          if what = "search" then
             what = "stop"
          end
       case "found":
          elem = VAR_ID_global_grp_circle.["el_" + string(VAR_ID_global_grp_circle_nextindex)]
          VAR_ID_global_grp_circle = VAR_ID_global_grp_circle - elem
          VAR_ID_global_grp_circle_len = VAR_ID_global_grp_circle_len - 1
          if ( VAR_ID_global_grp_circle_nextindex <= VAR_ID_global_grp_circle_len ) then
            VAR_ID_global_grp_circle_nextniden = VAR_ID_global_grp_circle.["el_" + 
                      string(VAR_ID_global_grp_circle_nextindex)].user_niden
          else
            // reset to first element
            VAR_ID_global_grp_circle_nextindex = 1
            VAR_ID_global_grp_circle_nextniden = VAR_ID_global_grp_circle_minniden 
          end
          work = "end"
       case "stop":
          if ( VAR_ID_global_grp_circle_nextindex < VAR_ID_global_grp_circle_len ) then
            VAR_ID_global_grp_circle_nextindex = VAR_ID_global_grp_circle_nextindex + 1
            VAR_ID_global_grp_circle_nextniden = VAR_ID_global_grp_circle.["el_" + 
                      string(VAR_ID_global_grp_circle_nextindex)].user_niden
          else
            // reset to first element
            VAR_ID_global_grp_circle_nextindex = 1
            VAR_ID_global_grp_circle_nextniden = VAR_ID_global_grp_circle_minniden 
          end
          work = "end"
       case "reset_search":
          // reset to first element
          VAR_ID_global_grp_circle_nextindex = 1
          VAR_ID_global_grp_circle_nextniden = VAR_ID_global_grp_circle_minniden 
          what = "search"
       case "exit":
          work = "end"
     end
    end           
   end           
   return (elem)

end


// ===================================================================

function ID_find_ellips_with_attr (id_prim)
   // Suchen einer Ellipse 
   //    mit Identifikator "id_prim" in der Elementliste der aktuellen View
   // return 0, wenn nicht gefunden

   elem = 0 

   if VAR_ID_global_grp_ellips_len > 0 then
    if (id_prim >= VAR_ID_global_grp_ellips_minniden and 
       id_prim <= VAR_ID_global_grp_ellips_maxniden ) then
      work = "work"
      what = "exit"

      if VAR_ID_global_grp_ellips_nextniden = id_prim then
         what = "found"
      else if VAR_ID_global_grp_ellips_nextniden < id_prim then
         what = "search"
      else
         what = "reset_search"
      end
      end
    end

    while work = "work" do
     switch what
       case "search":
         while ( VAR_ID_global_grp_ellips_nextindex < VAR_ID_global_grp_ellips_len and
                 what = "search" ) do
            VAR_ID_global_grp_ellips_nextindex = VAR_ID_global_grp_ellips_nextindex + 1   
            VAR_ID_global_grp_ellips_nextniden = VAR_ID_global_grp_ellips.["el_" 
                      + string(VAR_ID_global_grp_ellips_nextindex)].user_niden 
            if VAR_ID_global_grp_ellips_nextniden = id_prim then
               what = "found"
            else if VAR_ID_global_grp_ellips_nextniden > id_prim then
               what = "exit"
            end
            end
          end
          if what = "search" then
             what = "stop"
          end
       case "found":
          elem = VAR_ID_global_grp_ellips.["el_" + string(VAR_ID_global_grp_ellips_nextindex)]
          VAR_ID_global_grp_ellips = VAR_ID_global_grp_ellips - elem
          VAR_ID_global_grp_ellips_len = VAR_ID_global_grp_ellips_len - 1
          if ( VAR_ID_global_grp_ellips_nextindex <= VAR_ID_global_grp_ellips_len ) then
            VAR_ID_global_grp_ellips_nextniden = VAR_ID_global_grp_ellips.["el_" + 
                      string(VAR_ID_global_grp_ellips_nextindex)].user_niden
          else
            // reset to first element
            VAR_ID_global_grp_ellips_nextindex = 1
            VAR_ID_global_grp_ellips_nextniden = VAR_ID_global_grp_ellips_minniden 
          end
          work = "end"
       case "stop":
          if ( VAR_ID_global_grp_ellips_nextindex < VAR_ID_global_grp_ellips_len ) then
            VAR_ID_global_grp_ellips_nextindex = VAR_ID_global_grp_ellips_nextindex + 1
            VAR_ID_global_grp_ellips_nextniden = VAR_ID_global_grp_ellips.["el_" + 
                      string(VAR_ID_global_grp_ellips_nextindex)].user_niden
          else
            // reset to first element
            VAR_ID_global_grp_ellips_nextindex = 1
            VAR_ID_global_grp_ellips_nextniden = VAR_ID_global_grp_ellips_minniden 
          end
          work = "end"
       case "reset_search":
          // reset to first element
          VAR_ID_global_grp_ellips_nextindex = 1
          VAR_ID_global_grp_ellips_nextniden = VAR_ID_global_grp_ellips_minniden 
          what = "search"
       case "exit":
          work = "end"
     end
    end           
   end           
   return (elem)

end

// ============================================================

function ID_find_plane_with_attr (id_view, id_prim)
   elem = 0
   if VAR_ID_global_grp_plane_len > 0 then
      grp = VAR_ID_global_grp_plane where 
            ( .user_viewid = id_view and .user_timid = id_prim )
      if len(grp) = 1 then
         elem = grp.first
         VAR_ID_global_grp_plane = 
             VAR_ID_global_grp_plane - elem
      end
   end
   return (elem)

end

// ============================================================

function ID_find_text_with_attr (id_view, id_prim)
   elem = 0
   if VAR_ID_global_grp_text_len > 0 then
      grp = VAR_ID_global_grp_text where 
            ( .user_viewid = id_view and .user_timid = id_prim )
      if len(grp) = 1 then
         elem = grp.first
         VAR_ID_global_grp_text = 
             VAR_ID_global_grp_text - elem
      end
    end
   return (elem)

end

// ============================================================

function ID_find_symbol_with_attr (id_view, id_prim)
   elem = 0
   if VAR_ID_global_grp_symbol_len > 0 then
      grp = VAR_ID_global_grp_symbol where 
            ( .user_viewid = id_view and .user_timid = id_prim )
      if len(grp) = 1 then
         elem = grp.first
         VAR_ID_global_grp_symbol = 
             VAR_ID_global_grp_symbol - elem
      end
   end
   return (elem)

end

// ============================================================

function ID_find_meas_with_attr (id_view, id_prim)
   // Suchen genau eines Masses
   //    mit Identifikator "id_prim" in der Elementliste der aktuellen View
   // return 0, wenn nicht gefunden
   // return 0 und Loeschen, wenn mehrere Elemente gefunden wurden

   elem = 0 
   if VAR_ID_global_grp_mass_len > 0 then
      grp = VAR_ID_global_grp_mass where .user_viewid = id_view 
                                     and .user_dimid  = id_prim
      if len(grp) = 1 then
         elem = grp.first
         VAR_ID_global_grp_mass = VAR_ID_global_grp_mass - elem
      else 
         if len(grp) > 1 then
            ID_delete_elem(grp)
         end
      end
   end
   return (elem)

end

// ============================================================

function ID_find_spline_with_attr (id_prim, etyp)
   // Suchen genau eines Splines vom Typ "etyp"
   //    mit Identifikator "id_prim" in der Elementliste der aktuellen View
   // return 0, wenn nicht gefunden
   // return 0 und Loeschen, wenn mehrere Elemente gefunden wurden

   elem = 0 

    if VAR_ID_global_grp_spline_len > 0 then
     if (id_prim >= VAR_ID_global_grp_spline_minniden and 
         id_prim <= VAR_ID_global_grp_spline_maxniden) then
        work = "work"
        what = "exit"
        if VAR_ID_global_grp_spline_nextniden = id_prim then
           what = "found"
        else if VAR_ID_global_grp_spline_nextniden < id_prim then
           what = "search"
        else
           what = "reset_search"
        end
        end
     end

     while work = "work" do
       switch what
         case "search":
           while ( VAR_ID_global_grp_spline_nextindex < VAR_ID_global_grp_spline_len and
                   what = "search" ) do
              VAR_ID_global_grp_spline_nextindex = VAR_ID_global_grp_spline_nextindex + 1   
              VAR_ID_global_grp_spline_nextniden = VAR_ID_global_grp_spline.["el_" 
                      + string(VAR_ID_global_grp_spline_nextindex)].user_niden 
              if VAR_ID_global_grp_spline_nextniden = id_prim then
                 what = "found"
              else if VAR_ID_global_grp_spline_nextniden > id_prim then
                 what = "exit"
              end
              end
            end
            if what = "search" then
               what = "stop"
            end
         case "found":
            elem = VAR_ID_global_grp_spline.["el_" + string(VAR_ID_global_grp_spline_nextindex)]
            VAR_ID_global_grp_spline = VAR_ID_global_grp_spline - elem
            VAR_ID_global_grp_spline_len = VAR_ID_global_grp_spline_len - 1
            if ( VAR_ID_global_grp_spline_nextindex <= VAR_ID_global_grp_spline_len ) then
              VAR_ID_global_grp_spline_nextniden = VAR_ID_global_grp_spline.["el_" + 
                      string(VAR_ID_global_grp_spline_nextindex)].user_niden
            else
              // reset to first element
              VAR_ID_global_grp_spline_nextindex = 1
            VAR_ID_global_grp_spline_nextniden = VAR_ID_global_grp_spline_minniden 
            end
            work = "end"
         case "stop":
            if ( VAR_ID_global_grp_spline_nextindex < VAR_ID_global_grp_spline_len ) then
              VAR_ID_global_grp_spline_nextindex = VAR_ID_global_grp_spline_nextindex + 1
              VAR_ID_global_grp_spline_nextniden = VAR_ID_global_grp_spline.["el_" + 
                      string(VAR_ID_global_grp_spline_nextindex)].user_niden
            else
              // reset to first element
            VAR_ID_global_grp_spline_nextindex = 1
            VAR_ID_global_grp_spline_nextniden = VAR_ID_global_grp_spline_minniden 
            end
            work = "end"
         case "reset_search":
            // reset to first element
            VAR_ID_global_grp_spline_nextindex = 1
            VAR_ID_global_grp_spline_nextniden = VAR_ID_global_grp_spline_minniden 
            what = "search"
         case "exit":
            work = "end"
       end
     end           

     if elem != 0 and elem.prim_type != etyp then 
        switch elem.prim_type
           case "ellips"  : ID_delete_elem(elem)
           case "contour" : ID_delete_cont(elem)
           case "spline"  : ID_delete_elem(elem)
        end
        elem = 0
     end
   end
   return (elem)

end

// ============================================================

function ID_find_world_with_attr (id_prim)
   // Suchen einer World
   //    mit Identifikator "id_prim" in der Elementliste der aktuellen View
   // return 0, wenn nicht gefunden

   elem = 0 
   grp = VAR_ID_global_grp_world  where .user_nview = 
      ( VAR_ID_global_name_ideas + string(id_prim))

   if not empty (grp) then 
      elem = grp.first
   end
   return (elem)

end

// ============================================================
function ID_get_ID_Parameters()
  // Get Parameters from Configuration File
  ref_object = top.list_globals.first
 
  //if not valid(ref_object.user_ID_DRAW) then
     // initialize using the default parameters of action
     //ideas_config()
  //end

  if valid(ref_object.user_ID_DRAW) then
     VAR_ID_global_drawing = ref_object.user_ID_DRAW
  else
     ID_creatt_user_attrib ( ref_object, "ID_DRAW", VAR_ID_global_drawing)
     VAR_ID_global_drawing = 0
  end

  if valid(ref_object.user_ID_MEASURE) then
     VAR_ID_global_MeasModify = ref_object.user_ID_MEASURE
  else
     ID_creatt_user_attrib ( ref_object, "ID_MEASURE", VAR_ID_global_MeasModify)
     VAR_ID_global_MeasModify = 2
  end

  if valid(ref_object.user_ID_TEXT) then
     VAR_ID_global_TextModify = ref_object.user_ID_TEXT
  else
     ID_creatt_user_attrib ( ref_object, "ID_TEXT", VAR_ID_global_TextModify)
     VAR_ID_global_TextModify = 2
  end

  if valid(ref_object.user_ID_SYMBOL) then
     VAR_ID_global_SymbolModify = ref_object.user_ID_SYMBOL
  else
     ID_creatt_user_attrib ( ref_object, "ID_SYMBOL", VAR_ID_global_SymbolModify)
     VAR_ID_global_SymbolModify = 2
  end

  if valid(ref_object.user_ID_VIEW) then
     VAR_ID_global_ViewModify = ref_object.user_ID_VIEW
  else
     ID_creatt_user_attrib ( ref_object, "ID_VIEW", VAR_ID_global_ViewModify)
     VAR_ID_global_ViewModify = 1
  end

  if valid(ref_object.user_ID_CENTERLINE) then
     VAR_ID_global_ClineAdd = ref_object.user_ID_CENTERLINE
  else
     ID_creatt_user_attrib ( ref_object, "ID_CENTERLINE", VAR_ID_global_ClineAdd)
     VAR_ID_global_ClineAdd = 0
  end
 
  if valid(ref_object.user_ID_LINESTYLE) then
     VAR_ID_global_LineStyle = ref_object.user_ID_LINESTYLE
  else
     ID_creatt_user_attrib ( ref_object, "ID_LINESTYLE", VAR_ID_global_LineStyle)
     VAR_ID_global_LineStyle = 1
  end
 
  if valid(ref_object.user_ID_DELETE) then
     VAR_ID_KeepDelete = ref_object.user_ID_DELETE
  else
     ID_creatt_user_attrib ( ref_object, "ID_DELETE", VAR_ID_KeepDelete)
     VAR_ID_KeepDelete = 1
  end

   // check the parameters
   if ( VAR_ID_global_LineStyle < 0 or
        VAR_ID_global_LineStyle > 1 ) then
      VAR_ID_global_LineStyle = 1
   end

   if ( VAR_ID_global_MeasModify < 0 or
        VAR_ID_global_MeasModify > 2 ) then
      VAR_ID_global_MeasModify = 2
   end

   if ( VAR_ID_global_TextModify < 0 or
        VAR_ID_global_TextModify > 2 ) then
      VAR_ID_global_TextModify = 2
   end

   if ( VAR_ID_global_SymbolModify < 0 or
        VAR_ID_global_SymbolModify > 2 ) then
      VAR_ID_global_SymbolModify = 2
   end

   if ( VAR_ID_global_ViewModify < 0 or
        VAR_ID_global_ViewModify > 1 ) then
      VAR_ID_global_ViewModify = 1
   end

   if ( VAR_ID_global_ClineAdd < 0 or
        VAR_ID_global_ClineAdd > 1 ) then
      VAR_ID_global_ClineAdd = 0
   end

   if ( VAR_ID_global_drawing < 0 or 
        VAR_ID_global_drawing > 3 ) then
      VAR_ID_global_drawing = 0
   end

   if ( VAR_ID_KeepDelete < 0 or
        VAR_ID_KeepDelete > 1 ) then
      VAR_ID_KeepDelete = 1
   end

   if ID_DEBUG then
      `ID_DRAW = ` [VAR_ID_global_drawing] nl
      `ID_CENTERLINE_ADD = ` [VAR_ID_global_ClineAdd] nl
      `ID_MEASURE_MODIFY = ` [VAR_ID_global_MeasModify] nl
      `ID_LINESTYLE_MODIFY = ` [VAR_ID_global_LineStyle] nl
      `ID_TEXT_MODIFY = ` [VAR_ID_global_TextModify] nl
      `ID_SYMBOL_MODIFY = ` [VAR_ID_global_SymbolModify] nl
      `ID_VIEW_MODIFY = ` [VAR_ID_global_ViewModify] nl
      `ID_KEEP_DELETE = ` [VAR_ID_KeepDelete] nl
   end
   return
end

// ============================================================

function ID_get_create_layer ( lname, status )
  // function: get or create layer with name 'lname'
  //   if layer exist
  //       - undo delete if necessary
  //       - unlock layer and edit status
  //   if more then one layer exist --> error_message
  // input:  lname   string: name of layer
  //         status  string: status of layer  
  //                 "active", "selectable" or "inactive"      
  //                 "no_changes" = keep status, don't edit
  // return: layer

  player = 0
  grpl = top.list_layer where .name = lname
  if empty(grpl) then
       player = layer_normal ( lname , status , false  ) 
       // attach attribute to identify
       // there could be defined more than one layer with the same name
       // e.g.: Layer test_1 has .user_lname = "test_1"
       set_attrib (player, "lname", lname)
  else
     if len(grpl) > 1 then
        grp = grpl where .user_lname = lname
        if len(grp) = 1 then
           player = grp.first
        else
           // Error
           ID_error_message ( 2, player, len(grpl), 0 )
           player = grpl.first
        end
     else 
        player = grpl.first
     end

     // set layer undeleted
     if player.deleted then
         undo_delete(player)
     end

     if status = "no_changes" then
        edit ( player ,  , , false)
     else
        edit ( player ,  , , false)
        edit ( player ,  ,status , false)
     end
  end

  if len(grpl) > 1 then
     ID_error_message ( 2, player, len(grpl), 0 )
  end
  return (player)
end

// ============================================================

function ID_move_to_layer (elem, itype, id_view )
   // itype = 0 --> NOT key dimension --> layer "make_up"
   // itype = 1 --> key dimension     --> layer "key"
   // itype = 2 --> error             --> layer "error"
   // itype = 3 --> text          --> layer "make_up" | layer "draw"
   // itype = 4 --> symbol, plane --> layer "make_up" | layer "draw"                                 

   switch itype
      case 0: if VAR_ID_measure_old = 0 then 
                 layer_move_objects ({elem}, VAR_ID_global_layer_make_up )
              else
                 layer_move_objects ({elem}, VAR_ID_measure_old.layer )
                 VAR_ID_measure_old = 0
              end
      case 1: if VAR_ID_measure_old = 0 then 
                 layer_move_objects ({elem}, VAR_ID_global_layer_key )
              else
                 layer_move_objects ({elem}, VAR_ID_measure_old.layer )
                 VAR_ID_measure_old = 0
              end
      case 2: layer_move_objects ({elem}, VAR_ID_global_layer_error )
      case 3: if VAR_ID_text_old = 0 then 
                 if id_view = 32 then
                    layer_move_objects ({elem}, VAR_ID_global_layer_draw )
                 else
                    layer_move_objects ({elem}, VAR_ID_global_layer_make_up )
                 end
              else
                 layer_move_objects ({elem}, VAR_ID_text_old.layer )
                 VAR_ID_text_old = 0
              end
      case 4: if VAR_ID_symbol_old = 0 then 
                 if id_view = 32 then
                    layer_move_objects ({elem}, VAR_ID_global_layer_draw )
                 else
                    layer_move_objects ({elem}, VAR_ID_global_layer_make_up )
                 end
              else
                 layer_move_objects ({elem}, VAR_ID_symbol_old.layer )
                 VAR_ID_symbol_old = 0
              end
   end

   return
end

// ============================================================

function ID_after_measure ( elem, itype, id_view, id_dim )
   // Anhaengen der Attributwerte "viewid" und "dimid" 
   // an Element "elem" (fuer communication file)
   // itype = 0 --> Informationsmass --> layer "make_up"
   //         1 --> treibendes Mass  --> layer "key"
   // id_view:  Identifikator fuer View 
   // id_dim:   Identifikator fuer Mass
    
   ID_creatt_user_attrib (elem, "viewid", id_view)
   ID_creatt_user_attrib (elem, "dimid" , id_dim)

   // move to layer
   ID_move_to_layer (elem, itype, id_view )

end


// ============================================================

function ID_after_dspline ( cont, id_view, id_prim )
   // Poligonisierter Spline wurde erzeugt
   //   besteht aus Linienstuecken, zusammengefasst in einer 
   //   Kontur
   // Anhaengen der I-DEAS Identifikatoren dspline an die 
   //   neuerzeugte Kontur und deren Unterelemente
   // cont     = contour
   // id_view  = View-Identifikator
   // id_prim  = Element-Identifikator
 
   // attach attributes to contour
   ID_cre_id_attr_spline ( cont, id_view, id_prim )
end

// ============================================================

function ID_cont_edit ( cont, grp_dx_dy, linestyle )

  // Edit x-, y-values of each point
  //     first point of each line
  //     last  point of last line
  // Edit the line style of contour "cont"

  switch linestyle 
      case "solid":      dick = 0.5
      case "dashed":     dick = 0.35
      case "dashdotted": dick = 0.25
  end

  i = 1
  while ( i <= len(cont.par_coe) ) do
     dx = grp_dx_dy.["el_" + string(i*2-1)]
     dy = grp_dx_dy.["el_" + string(i*2)]
 
     // get line
     line = cont.par_coe.["el_" + string(i)]

     // edit line style 
     if VAR_ID_global_LineStyle = 0 then
        edit ( line , , { linestyle dick} , , , )
     end
     ID_undo_delete(line)
 
     // get first point of each line
     point = line.par_p1

     if abs(point.x - dx - VAR_ID_global_orig_view.x) > VAR_epsilon then
        edit(point.par_dx, dx)
     end
     if abs(point.y - dy - VAR_ID_global_orig_view.y) > VAR_epsilon then
        edit(point.par_dy, dy)
     end

     i = i + 1
  end
 
  // last point
  dx = grp_dx_dy.["el_" + string(i*2-1)]
  dy = grp_dx_dy.["el_" + string(i*2)]

  // get last point of last line
  point = line.par_p2
 
  if abs(point.y - dy - VAR_ID_global_orig_view.x) > VAR_epsilon then
     edit(point.par_dx, dx)
  end
  if abs(point.y - dy - VAR_ID_global_orig_view.y) > VAR_epsilon then
     edit(point.par_dy, dy)
  end
  ID_undo_delete(cont)

end

// ============================================================

function ID_before_dspline(id_view, id_prim, nr_lines)

  elem = 0
  // search for spline with attribute
  spline  = ID_find_spline_with_attr (id_prim, "contour")

  if spline != 0 then
     if len(spline.par_coe) = nr_lines then
        // spline contour has the same number of lines
        // return for edit
        elem =  spline
     else
        // old contour and its lines have to be deleted
        ID_delete_cont(spline)
     end
  end
  return (elem)

end

// ============================================================

function ID_before_measure(itype, id_view, id_dim )
// function: search for measure with attribute
// input: 
//   itype = 0 --> Informationsmass --> layer "make_up"
//           1 --> treibendes Mass  --> layer "key"
//   id_view:  Identifikator fuer View 
//   id_dim:   Identifikator fuer Mass
// return (meas_old)  int        : old measure if exists

  measure_old = ID_find_meas_with_attr (id_view, id_dim)
  return (measure_old)

end

// ============================================================

function ID_measure_angle2lines ( meas_old, id_view, id_prim, dtype, mtype,
   control, pretext, tol, comment, ID_FONT, ID_ITALIC, ID_MODUS, height,
   anglelen, mtpos, l1, l2, sel, pos)
// function: create/edit measure between two elements
// input: 
//   meas_old  int        : old measure if exixts
//   id_view   int        : view identifier
//   id_prim   int        : primitive identifier
//   dtype     int        : 0 --> information dimension (layer "make_up")
//                          1 --> key dimension (layer "key")
//   mtype     string     : shortmeasure = "is_shortmeasure", "is_longmeasure" 
//   control   group      : control_rec  
//   pretext              : string              
//   tol                  : posttext            
//   comment              : string              
//   ID_FONT              : font_rec       
//   ID_ITALIC            : angle               
//   ID_MODUS             : prop                
//   height               : length              
//   anglelen             : anglelen_enu  "is_longmeasure" / "is_shortmeasure"                
//   mtpos                : wcoord       **** to calculate                    
//   l1                   : line             
//   l2                   : line             
//   sel                  : doubleboolean              
//   pos                  : posmeas             
//
//  return:  --

  elem = 0
  if meas_old = 0 then
     elem =  measure_angle2lines ( control, pretext, tol, comment,
                                   ID_FONT, ID_ITALIC, ID_MODUS, height,
                                   mtpos, anglelen, l1, l2, pos, sel)

     ID_after_measure ( elem, dtype, id_view, id_prim )
  else if VAR_ID_global_MeasModify = 0 then
     elem = meas_old
     co = coord_absolute  (  { 0, 0, 0 }  ) 
     edit ( elem, control, pretext, tol, comment,
                  ID_FONT, ID_ITALIC, ID_MODUS, height,
                  mtpos, anglelen, l1, l2, pos, sel)
  else if VAR_ID_global_MeasModify = 1 then
     elem = meas_old
     edit ( elem, control, pretext, tol, comment, , , , , , , l1, l2, , )
  else
     elem = meas_old
     edit ( elem, , , , , , , , , , , l1, l2, , )
  end
  end
  end
  return
end

// ============================================================

function ID_measure_chain ( meas_old, id_view, id_prim, dtype, 
   control, pretext, tol, comment, ID_FONT, ID_ITALIC, ID_MODUS, height,
   pangle, mtpos, p1, p3, a, p2)
// function: create/edit measure between two elements
// input: 
//   meas_old  int        : old measure if exixts
//   id_view   int        : view identifier
//   id_prim   int        : primitive identifier
//   dtype     int        : 0 --> information dimension (layer "make_up")
//                          1 --> key dimension (layer "key")
//   control   group      : control_rec  
//   pretext              : string              
//   tol                  : posttext            
//   comment              : string              
//   ID_FONT              : font_rec       
//   ID_ITALIC            : angle               
//   ID_MODUS             : prop                
//   height               : length              
//   pangle               : angle               
//   mtpos                : wcoord              
//   p1                   : point  basis point              
//   p2                   : point  point to measure            
//   a                    : angle              
//   p3                   : point  position of measure line             
//
//  return:  --

  elem = 0
  if meas_old = 0 then
     pos = posmeas_onpoint (p3)
     elem = measure_relative ( control, pretext, tol, comment,
            ID_FONT, ID_ITALIC, ID_MODUS, height,
              a, 0, p1, {{ p2, {0,0,0} }}, pos)
     ID_after_measure ( elem, dtype, id_view, id_prim )
  else if VAR_ID_global_MeasModify = 0 then
     elem = meas_old
     pos = posmeas_onpoint (p3)
     edit  (elem, control, pretext, tol, comment,
            ID_FONT, ID_ITALIC, ID_MODUS, height,
              a, 0, p1, {{ p2, {0,0,0} }}, pos)
  else if VAR_ID_global_MeasModify = 1 then
     elem = meas_old
     if valid (elem.par_dm) then
        wcoord = elem.par_dm
        edit  (elem, control, pretext, tol, comment,
             , , , , a, , p1, {{ p2, wcoord }}, )
     else
        edit  (elem, control, pretext, tol, comment,
             , , , , a, , p1, {{ p2, {0,0,0} }}, )
     end
  else
     elem = meas_old
     if valid (elem.par_dm) then
        wcoord = elem.par_dm
        edit  (elem, , , , ,
             , , , , a, , p1, {{ p2, wcoord }}, )
     else
        edit  (elem, , , , ,
             , , , , a, , p1, {{ p2, {0,0,0} }}, )
     end
  end
  end
  end
  return
end


// ============================================================

function ID_measure_diamofcircle ( meas_old, id_view, id_prim, dtype,
   control, pretext, tol, comment, ID_FONT, ID_ITALIC, ID_MODUS, height,
   mtpos, c, pangle, pos)
// function: create/edit measure between two elements
// input: 
//   meas_old  int        : old measure if exixts
//   id_view   int        : view identifier
//   id_prim   int        : primitive identifier
//   dtype     int        : 0 --> information dimension (layer "make_up")
//                          1 --> key dimension (layer "key")
//   control   group      : control_rec  
//   pretext              : string              
//   tol                  : posttext            
//   comment              : string              
//   ID_FONT              : font_rec       
//   ID_ITALIC            : angle               
//   ID_MODUS             : prop                
//   height               : length              
//   pangle               : angle               
//   mtpos                : wcoord              
//   c                    : circle           
//   pos                  : posmeas             
//
//  return:  --

  elem = 0
  if meas_old = 0 then
      elem = measure_diamofcircle ( control, pretext, tol, comment,
                                    ID_FONT, ID_ITALIC, ID_MODUS, height,
                                    pangle, mtpos, c, pos )
     ID_after_measure ( elem, dtype, id_view, id_prim )
  else if VAR_ID_global_MeasModify = 0 then
     elem = meas_old
     edit ( elem, control, pretext, tol, comment, 
                  ID_FONT, ID_ITALIC, ID_MODUS, height,
                  pangle, mtpos, c, pos )
  else if VAR_ID_global_MeasModify = 1 then
     elem = meas_old
     edit ( elem, control, pretext, tol, comment, , , , , , , c,  )
  else
     elem = meas_old
     edit ( elem, , , , , , , , , , , c,  )
  end
  end
  end
  return
end

// ============================================================

function ID_measure_plcplc ( meas_old, id_view, id_prim, dtype,
   control, pretext, tol, comment, ID_FONT, ID_ITALIC, ID_MODUS, height,
   pangle, el1, el2, pos)
// function: create/edit measure between two elements
// input: 
//   meas_old  int        : old measure if exixts
//   id_view   int        : view identifier
//   id_prim   int        : primitive identifier
//   dtype     int        : 0 --> information dimension (layer "make_up")
//                          1 --> key dimension (layer "key")
//   control   group      : control_rec  
//   pretext              : string              
//   tol                  : posttext            
//   comment              : string              
//   ID_FONT              : font_rec       
//   ID_ITALIC            : angle               
//   ID_MODUS             : prop                
//   height               : length              
//   pangle               : angle               
//   el1                  : alternative       
//      p                 : point               
//      l                 : line                
//      c                 : circle              
//   el2                  : alternative         
//      p                 : point               
//      l                 : line                
//      c                 : circle              
//   pos                  : point : text location             
//
//  return:  --

  elem = 0
  if meas_old = 0 then
     posi = posmeas_onpoint (pos)
     mtposi = coord_onpoint (pos)
     elem = measure_plc1plc2 ( control, pretext, tol, comment, 
			   ID_FONT, ID_ITALIC, ID_MODUS, height,  pangle, 
                               mtposi, el1, el2, posi, 0 )
     if elem != 0 then
        ID_after_measure ( elem, dtype, id_view, id_prim )
     end      
  else if VAR_ID_global_MeasModify = 0 then
    elem = meas_old
    posi = posmeas_onpoint (pos)
    mtposi = coord_onpoint (pos)
    edit ( elem , control, pretext, tol, comment, 
                  ID_FONT, ID_ITALIC, ID_MODUS, height,  pangle, 
                  mtposi, el1, el2,  posi, 0 )
     
  else if VAR_ID_global_MeasModify = 1 then
    elem = meas_old
    edit ( elem, control, pretext, tol, comment, 
           , , , , , , el1, el2, , )
  else
    edit ( elem, , , , , , , , , , , el1, el2, , )
  end
  end
  end

  return
end

// ============================================================

function ID_measure_radiusofsect ( meas_old, id_view, id_prim, dtype, mtype,
   control, pretext, tol, comment, ID_FONT, ID_ITALIC, ID_MODUS, height,
   pangle, mtpos, c, pos)
// function: create/edit measure between two elements
// input: 
//   meas_old  int        : old measure if exixts
//   id_view   int        : view identifier
//   id_prim   int        : primitive identifier
//   dtype     int        : 0 --> information dimension (layer "make_up")
//                          1 --> key dimension (layer "key")
//   mtype     string     : isshortradiusmeas = "is_longradiusmeasure"  ,  "is_shortradiusmeasure" 

//   control   group      : control_rec  
//   pretext              : string              
//   tol                  : posttext            
//   comment              : string              
//   ID_FONT              : font_rec       
//   ID_ITALIC            : angle               
//   ID_MODUS             : prop                
//   height               : length              
//   pangle               : angle               
//   mtpos                : wcoord              
//    c                    : circle              
//   pos                  : posmeas             
//
//  return:  --

  elem = 0
  if meas_old = 0 then
     if tol = "" then
        elem = measure_radiusofsect ( control, pretext, , comment,
                 ID_FONT, ID_ITALIC, ID_MODUS, height, 
                 mtpos, mtype, c, pos )
     else
        elem = measure_radiusofsect ( control, pretext, tol, comment,
                 ID_FONT, ID_ITALIC, ID_MODUS, height, 
                 mtpos, mtype, c, pos )
     end
     ID_after_measure ( elem, dtype, id_view, id_prim )
  else if VAR_ID_global_MeasModify = 0 then
     elem = meas_old
     if tol = "" then
       edit ( elem, control, pretext, , comment, 
                    , , , height, mtpos, mtype, c, pos )
     else
       edit ( elem, control, pretext, tol, comment, 
                    , , , height, mtpos, mtype, c, pos )
     end
  else if VAR_ID_global_MeasModify = 1 then
     elem = meas_old
     if tol = "" then
       edit ( elem, control, pretext, , comment, , , , , , , c,  )
     else
       edit ( elem, control, pretext, tol, comment, , , , , , , c,  )
     end
  else
     elem = meas_old
     edit ( elem, , , , , ,  , , , , , c, )
  end
  end
  end
  return
end


// ============================================================
function ID_before_symbol (id_view, id_prim)
  // Texte und Symbole liegen im layer "make_up"
  // input
  //   id_view:  view identifier from IDEAS 
  //   id_prim:  identifier for symbol
  // return 0:  create symbol
  //        1:  edit symbol -- not yet implemented
  //        2:  do nothing

  // search for symbol with attribute
  iSymbolSwitch = VAR_ID_global_SymbolModify

  VAR_ID_symbol_old = ID_find_symbol_with_attr (id_view, id_prim)
  if VAR_ID_symbol_old = 0 then
     iSymbolSwitch = 0
  else if VAR_ID_global_SymbolModify = 1 and VAR_ID_symbol_old.def_type != "balloon" then
     // delete old symbol and create it new except the balloon symbol
     delete(VAR_ID_symbol_old)
     iSymbolSwitch = 0
  end
  end

  return (iSymbolSwitch)

end

// ============================================================
function ID_before_plane (id_view, id_prim)

  // Planes liegen im layer "make_up"
  // input
  //   id_view:  view identifier from IDEAS 
  //   id_prim:   Identifikator fuer text oder symbol
  // return 0:  create plane
  //        1:  edit plane = do nothing
  //        2:  do nothing

  // search for plane with attribute
  iSymbolSwitch = VAR_ID_global_SymbolModify

  VAR_ID_symbol_old = ID_find_plane_with_attr (id_view, id_prim )
  if VAR_ID_symbol_old = 0 then
     iSymbolSwitch = 0
  else if VAR_ID_global_SymbolModify = 1 then
     // delete old symbol and create it new
     delete(VAR_ID_symbol_old)
     iSymbolSwitch = 0
  end
  end
  return (iSymbolSwitch)

end

// ============================================================

function ID_before_text( id_view, id_prim )
  // Texte und Symbole liegen im layer "make_up"
  // input
  //   id_view:  view identifier from IDEAS
  //   id_prim:   Identifikator fuer text oder symbol
  // return 0:  create text
  //        1:  edit text
  //        2:  do nothing

  // search for text with attribute
  iTextSwitch = VAR_ID_global_TextModify

  VAR_ID_text_old = ID_find_text_with_attr (id_view, id_prim)
  if VAR_ID_text_old = 0 then
     iTextSwitch = 0
  else
     if VAR_ID_global_TextModify = 2 then
       // get the symbol and take it from the list
       // otherwise it would be deleted at the end
       // (sometimes: I-DEAS text --> Design text + symbol)
       symbol_old = ID_find_symbol_with_attr
                 (VAR_ID_text_old.user_viewid, 
                  VAR_ID_text_old.user_timid)
     end
  end
  return (iTextSwitch)

end

// ============================================================

function ID_create_text_height (hight) 
   // Suchen nach Objekt length_absolut 
   // Wenn nicht vorhanden, dann erzeugen
   // wird nur beim Erzeugen von Massen verwendet

   grp = { }
   if len(VAR_ID_global_grp_length) > 0 then
       grp = VAR_ID_global_grp_length where 
             ( .user_viewid = -111 and .norm = hight)
   end
   if len(grp) > 0 then
      length_hight = grp.first
   else     
      length_hight = length_absolute(hight)
      ID_creatt_user_attrib (length_hight, "viewid", -111 )
      VAR_ID_global_grp_length = VAR_ID_global_grp_length + length_hight
   end
   
   return(length_hight)

end

// ============================================================

function ID_create_texttext_height (hight) 
// search object length of def_type "absolut" 
// If not exist: create them
// Used to create text height of object text

  grp = { }
  if len(VAR_ID_global_grp_length) > 0 then
     grp = VAR_ID_global_grp_length where 
           ( .user_viewid = -222 and .norm = hight)
  end
  if len(grp) > 0 then
     length_hight = grp.first
  else     
     length_hight = length_absolute(hight)
     ID_creatt_user_attrib (length_hight, "viewid", -222 )
     VAR_ID_global_grp_length = VAR_ID_global_grp_length + length_hight
  end
   
  return(length_hight)

end

// ============================================================

function ID_create_posmeas_length ( str , d ) 
   // CHECK create posmeas
   elem =  posmeas_absolute (d)
   //   return(elem) 
   return(elem)
end

// ============================================================
 
function ID_create_coord_absolute ( dx, dy ) 
   elem = coord_absolute ( { dx,  dy, 0 } )
   return(elem)
end

// ============================================================

function ID_create_plane ( id_view, id_prim, elayer, contin, 
                           dist,    angle )
  // input
  //   id_view:  int     identifier of active view
  //   id_prim:  int     identifier of primitive
  //   elayer    int     I-DEAS element layer
  //   contin:   group   group of lines and circles
  //   dist:     double  distance between hatching lines
  //   angle:    double  hatching angle
  // return: plane

  // create hatching

  if ID_DEBUG then
     `plane ` [id_view] ` `  [id_prim] nl 
  end
  cont = contin where valid(.prim_type)

  if VAR_ID_global_type_view = 7 then
     // z: one behind "hiding plane des Ausschnittes"
     elem = plane_ofelements ( VAR_ID_global_z_detail_plane, VAR_ID_global_color_plane, 
         {  "hatch_single", true }, cont, dist, angle  )
  else 
     elem = plane_ofelements ( VAR_ID_global_z_ideas_plane, VAR_ID_global_color_plane,
         {  "hatch_single", true }, cont, dist, angle  )
  end

  if valid(elem) then 
     // attach attributes and move to layer
     itype = 4
     ID_cre_id_attr_textsymbol (elem,itype,id_view,id_prim)
  else
     if ID_DEBUG then
        `plane not created` [id_view] ` `  [id_prim] nl 
     end
     elem = 0 
  end
 
  // Loeschen der Punkte der Kontur und zuruecksetzen der Liste.
  // Innerhalb dieser Liste werden Punkte ueber "search" gefangen 
  // um Genauigkeitsprobleme zu umgehen.

  delete ( VAR_ID_global_grp_ptshat )
  VAR_ID_global_grp_ptshat = {}
 
  return (elem)

end

// ============================================================

function ID_after_symbol ( elem, id_view, id_prim )
   // Nachbehandlung von Symbolen
   // id_view:  view identifier 
   // id_prim:  identifier for symbol
    
   if elem != 0 then
     itype = 4
     ID_cre_id_attr_textsymbol (elem,itype,id_view,id_prim)
   end
   return 
end

// ============================================================

function ID_create_section ( ID_FONT, ID_ITALIC, modus, height,
         grp1, str, p1, p2, id_view, id_prim )

// input paramaters
//   ID_FONT, ID_ITALIC, modus, height:   text properties
//   grp1  :   grp of points
//   str   :   e.g. "A"
//   p1    :   point 1 of text location
//   p2    :   point 2 of text location
//   id_view:  view identifier from IDEAS
//   id_prim:  primitive identifier from IDEAS
//
// return: symbol

  secsymbol = "dotted"   // "filled"  

  // create grp_psw = sequence of 
  //     {{ point,string,wcoord}, {point,string,wcoord} ...}               
  // first element
  w1 = coord_onpoint (p1)
  grp_psw = { { grp1.el_1, str, w1} }
  liend = len(grp1)
  i = 2
  while i < liend do
     grp_psw = grp_psw + { { grp1.["el_" + string(i)],
                          string_absolute (""),
                          wcoord_absolute ({ 0, 0, 0 }) } }
     i = i + 1
  end

  // last element
  w2 = coord_onpoint (p2)
  grp_psw = grp_psw + { { grp1.["el_" + string(liend)], str, w2 } }

  if VAR_ID_symbol_old = 0 then
     elem = symbol_section ( ID_FONT, ID_ITALIC, modus, height, 
                  secsymbol, grp_psw )
     // attach attributes and move to layer
     itype = 4
     ID_cre_id_attr_textsymbol (elem,itype,id_view,id_prim)   
  else
     elem = VAR_ID_symbol_old
     edit (elem, ID_FONT, ID_ITALIC, modus, height, 
                  secsymbol, grp_psw )
     if elem.deleted then
        undo_delete(elem)
     end
  end
  return (elem)
end

// ============================================================

function ID_edit_section ( grp1, str )
//   grp1  :   grp of points
//   str   :   e.g. "A"

  elem = VAR_ID_symbol_old

  // edit parameter
  if valid(elem.par_star_section) then
     `valid elem.par_star_section` nl
     `len(elem.par_star_section) =` [len(elem.par_star_section)] nl
  end
  // edit (elem, , , , , , grp_psw )
  if elem.deleted then
     undo_delete(elem)
  end
  return (elem)
end

// ============================================================

function ID_cre_id_attr_view ( elem, id_view)
   // Anhaengen der I-DEAS Identifikatoren an die Elemente
   // elem     = Element
   // id_view  = View-Identifikator
   //
   // Zur eindeutigen Identifikation noch VAR_ID_global_name_ideas
 
   ID_creatt_user_attrib (elem, "nview" , VAR_ID_global_name_ideas 
                                 + string(id_view))

end

// ============================================================

function ID_cre_id_attr ( elem, id_view, id_prim )
   // Anhaengen der I-DEAS Identifikatoren an die Elemente
   // elem     = Element
   // id_view  = View-Identifikator
   // id_prim   = Element-Identifikator
 
   ID_creatt_user_attrib (elem, "nname", id_view) 
   ID_creatt_user_attrib (elem, "niden", id_prim)

end

// ============================================================

function ID_cre_id_attr_spline ( elem, id_view, id_prim )
   // Anhaengen der I-DEAS Identifikatoren an spline
   // elem     = spline, ellipse
   // id_view  = View-Identifikator
   // id_prim  = Element-Identifikator
 
   // attach attributes to spline, ellipse
   ID_creatt_user_attrib (elem, "nname",  id_view) 
   ID_creatt_user_attrib (elem, "nspline", id_prim)
   // wird benoetigt fuers Loeschen
   ID_creatt_user_attrib (elem, "niden", id_prim)
end

// ============================================================

function ID_cre_id_attr_textsymbol (elem,itype,id_view,id_prim)
   // Attach the I-DEAS identifier to text and symbols
   // elem     = text, symbol
   // itype    = 3 text
   //            4 symbol 
   //            5 points of view boundary, 
   //              plane which cover all detail hatching planes
   // id_view  = View-Identifikator
   // id_prim  = Element-Identifikator
 

   // attach attributes to text, symbol
   ID_creatt_user_attrib (elem, "viewid", id_view)
   ID_creatt_user_attrib (elem, "timid" , id_prim)

   // move to layer "make_up" 
   ID_move_to_layer (elem, itype, id_view )

end

// ============================================================

function ID_cre_id_attr_detail (elem,id_view,id_prim)
   // Attach the I-DEAS identifier to points, plane
   //    for view detail
   // elem     = point, plane
   // id_view  = View-Identifikator
   // id_prim  = Element-Identifikator
 
   // attach attributes to text, symbol
   ID_creatt_user_attrib (elem, "viewid", id_view)
   ID_creatt_user_attrib (elem, "detail", id_prim)

   // move to layer "make_up" 
   layer_move_objects ({elem}, VAR_ID_global_layer_make_up )

end

// ============================================================

function ID_create_point(id_view, id_prim, dx, dy)
   /* Erzeugen eines Punktes in der aktuellen View   */
   /*   Eingabe:                                     */
   /*      id_view: Attributwert fuer Attr. "nname"  */
   /*      dx   : x-Wert realativ zur lokalen World  */
   /*      dy   : y-Wert realativ zur lokalen World  */
   /*                                                */
   /*   Ausgabe:                                     */
   /*      Point                                     */
   /*                                                */
   /*  Beschreibung                                  */
   /*  Wenn id_prim = 0 : wird Punkt erzeugt und     */
   /*       kein Attribut angehaengt                 */
   /*       und gleich wieder geloescht              */
   /*  Wenn id_prim = -999 :                         */
   /*       wird Punkt gesucht mit Abstand           */
   /*       VAR_epsilon_schraffur; wenn nicht        */
   /*       gefunden wird er erzeugt.                */
   /*  Sonst:                                        */
   /*    Suchen, ob Punkt mit diesem Attribut        */
   /*    Wenn er schon existiert, werden die Values  */
   /*    verglichen und gegebenfalls die Werte       */
   /*    editiert. Der Punkt erhaelt das eindeutige  */
   /*    Attribut "nname" mit Wert "id_view"         */
   /*                                                */

   elem = 0   /* zu erzeugender neuer Punkt */
   switch id_prim 
      case 0:
         elem = point_relative(VAR_ID_global_orig_view,dx,dy)
         delete (elem)
      case -999: 
         // Suchen nach Punkten mit Abstand VAR_epsilon_schraffur
         // Genauigkeitsprobleme beim Schraffieren (aus I-DEAS) 
         if len(VAR_ID_global_grp_ptshat) > 0 then
            i = 1 
            while (i <= len(VAR_ID_global_grp_ptshat) and elem = 0) do 
                obj = VAR_ID_global_grp_ptshat.["el_" + string(i)]
                if ( (abs (obj.par_dx.norm - dx) < VAR_epsilon_schraffur) and
                     (abs (obj.par_dy.norm - dy) < VAR_epsilon_schraffur) ) then
                   elem = obj
                end
                i = i + 1
            end
            if elem = 0 then
               elem = point_relative(VAR_ID_global_orig_view,dx,dy)
               VAR_ID_global_grp_ptshat = VAR_ID_global_grp_ptshat + elem 
            else
              delete (elem)
               VAR_ID_global_grp_ptshat = VAR_ID_global_grp_ptshat where not .deleted
            end
         else
            elem = point_relative(VAR_ID_global_orig_view,dx,dy)
            VAR_ID_global_grp_ptshat = VAR_ID_global_grp_ptshat + elem  
         end
    otherwise:
        /* search point with attribute in actual view */
        elem = ID_find_point_with_attr (id_prim)
        if elem = 0 then
           /* create point and attach attribute */
           elem = point_relative(VAR_ID_global_orig_view,dx,dy)
           ID_cre_id_attr ( elem, id_view, id_prim )
        else
           /* Editieren des Punktes, wenn Values unterschiedlich sind */
           if abs(elem.x - dx - VAR_ID_global_orig_view.x) > VAR_epsilon then
              edit(elem.par_dx, dx)
           end 
           if abs(elem.y - dy - VAR_ID_global_orig_view.y) > VAR_epsilon then
              edit(elem.par_dy, dy)
           end 
           ID_undo_delete(elem)
        end     
   end
   return (elem)

end

// ============================================================

function ID_create_line(id_view,id_prim,elayer,str1,str2,p1,p2)
   /* Erzeugen einer Linie in der aktuellen View, */
   /*    Wenn sie schon existiert, wird die  */
   /*    gefundene Linie zurueckgegeben */

   line = 0   /* zu erzeugende neue Linie */

   dick = 3   // Linienstaerke dick  

   switch str1 
      case "solid":      dick = 0.5
      case "dashed":     dick = 0.35
      case "dashdotted": dick = 0.25
                         if VAR_ID_global_ClineAdd = 1 then
                            str2 = "is_midline"
                         end
   end  

   switch id_prim 
     case 0:
       line = line_pointpoint ( VAR_ID_global_Z, { str1 dick} , str2, p1, p2)
       if not valid(line) then
          return(0)
       end
       delete (line)
     case -999: 
        // create visible polyline
        line = line_pointpoint  ( VAR_ID_global_Z, { str1 dick} , str2, p1, p2)
     otherwise:
      /* Suchen der Linie mit Namen in der akt. View */

      line = ID_find_line_with_attr (id_prim)
      if  line = 0 then
          /* create line and attach attribute */

          line = line_pointpoint  ( VAR_ID_global_Z, { str1 dick} , str2, p1, p2)
          if not valid(line) then
             return(0)
          end
          ID_cre_id_attr ( line, id_view, id_prim )
      else 
          /* Anfangs- und Endpunkte koennen sich geaendert haben */
          if VAR_ID_global_LineStyle = 0 then
             edit ( line , , { str1 dick} , str2 , p1 , p2 )
          else
             edit ( line , , , str2 , p1 , p2 )
          end
          ID_undo_delete(line)
      end
   end

   return (line)

end

// ============================================================

function ID_create_arc(id_view, id_prim,elayer,str1,str2,p1,p2,p3)
   arc = 0   /* zu erzeugender neuer Bogen */
   dick = 3   // Linienstaerke dick  
   // "with_axes" / "no_axes"   
   switch str1 
      case "solid":      dick = 0.5
      case "dashed":     dick = 0.35
      case "dashdotted": dick = 0.25
   end
  
   if id_prim = 0 then
      arc = circle_arc2pointsbegin  ( VAR_ID_global_Z, { str1 dick}, "no_axes", str2, p1, p2, p3)
      /* p3 auf Endpunkt von Arc editieren */
      edit (p3 , , arc.x3 - VAR_ID_global_orig_view.x,
                   arc.y3 - VAR_ID_global_orig_view.y)
      delete (arc)
   else
      // Suchen des Elementes im Zeichnungslayer
      arc = ID_find_circle_with_attr (id_prim)
 
      if  arc = 0 then
          /* Erzeugen und Benennen des Bogens */
          arc = circle_arc2pointsbegin  ( VAR_ID_global_Z, { str1 dick}, "no_axes", str2, p1, p2, p3)
          ID_cre_id_attr ( arc, id_view, id_prim )

          /* p3 auf Endpunkt von Arc editieren */
          edit (p3 , , arc.x3 - VAR_ID_global_orig_view.x,
                       arc.y3 - VAR_ID_global_orig_view.y)
      else 
        if arc.def_type = "centerradius" then
          // changed from circle to arc
          delete_attrib(arc, "nname" )
          delete_attrib(arc, "niden" )
          delete (arc)
          arc = circle_arc2pointsbegin  ( VAR_ID_global_Z, { str1 dick}, , str2, p1, p2, p3)
          ID_cre_id_attr ( arc, id_view, id_prim )
        else        
          if VAR_ID_global_LineStyle = 0 then
             edit ( arc , , { str1 dick} , , str2, p1, p2, p3 )
          else
             edit ( arc , ,  , , str2, p1, p2, p3 )
          end
        end
        edit (p3 , , arc.x3 - VAR_ID_global_orig_view.x,
                     arc.y3 - VAR_ID_global_orig_view.y)
        ID_undo_delete(arc)
     end
   end
           
   return (arc)

end

// ============================================================

function ID_create_arc_3p(id_view, id_prim,elayer,str1,str2,str3,p1,p2,p3)
   // used only for creating hatch planes
   arc = 0   /* zu erzeugender neuer Bogen */
   dick = 3   // Linienstaerke dick  
   // str1 .. "solid", ...
   // str2 .. "is_arc"
   // str3 .. "over_p2"
   //    
   switch str1 
      case "solid":      dick = 0.5
      case "dashed":     dick = 0.35
      case "dashdotted": dick = 0.25
   end
  
   if id_prim = 0 then
       arc =  circle_3elements ( VAR_ID_global_Z, { str1 dick}, "no_axes",
                                 str2, str3,
                                 p1, p2, p3, { 0, false, false, false } )
       if not valid(arc) then
          arc = line_pointpoint ( VAR_ID_global_Z, { str1 dick} , "is_limited", p1, p3)
          return (arc)
       end
       // delete arc and his effects --> invisible
       delete (arc)
       if ( len(arc.created_by.list_effects) > 0 ) then
          delete (arc.created_by.list_effects)  // effects must also be deleted 
       end
 
       // delete midpoint of arc and take it from hatch point list
       delete (p2)
       VAR_ID_global_grp_ptshat = VAR_ID_global_grp_ptshat where not .deleted
   end           
   return (arc)

end

// ============================================================

function ID_create_circle(id_view, id_prim,elayer,str1,str2,p1,r1)

   circle = 0   /* zu erzeugender neuer Bogen */
   dick = 3   // Linienstaerke dick  

   switch str1 
      case "solid":      dick = 0.5
      case "dashed":     dick = 0.35
      case "dashdotted": dick = 0.25
   end  

   if id_prim = 0 then
      circle = circle_centerradius  ( VAR_ID_global_Z, { str1 dick}, str2, p1, r1) 
      delete (circle)
   else
      // Suchen des Elementes im Zeichnungslayer
      circle = ID_find_circle_with_attr (id_prim)
 
      if circle = 0 then
         /* Erzeugen und Benennen der Linie */
         circle = circle_centerradius  ( VAR_ID_global_Z, { str1 dick}, str2, p1, r1)
         ID_cre_id_attr ( circle, id_view, id_prim )
      else 
        if circle.def_type = "centerradius" then
           if VAR_ID_global_LineStyle = 0 then
              edit ( circle , , { str1 dick}, str2, p1, r1 )
           else
              edit ( circle , , , str2, p1, r1 )
           end
        else
          // whas transferred before as an arc
          //changed from circle to arc
          delete_attrib(circle, "nname" )
          delete_attrib(circle, "niden" )
          delete (circle)
          circle = circle_centerradius  ( VAR_ID_global_Z, { str1 dick}, str2, p1, r1)
          ID_cre_id_attr ( circle, id_view, id_prim )
        end
        ID_undo_delete(circle)
      end
    end
           
   return (circle)

end

// ============================================================

function ID_create_ellipse(id_view, id_prim,elayer,str1,p1,r1, r2, r3)

   ellipse = 0   /* zu erzeugender neuer Bogen */
   dick = 3   // Linienstaerke dick  
   switch str1 
      case "solid":      dick = 0.5
      case "dashed":     dick = 0.35
      case "dashdotted": dick = 0.25
   end  

   if id_prim = 0 then
       ellipse = ellips_angle2lengths  ( VAR_ID_global_Z, { str1 dick}, p1, r1, r2, r3)
       delete (ellipse)
   else
      // Suchen des Elementes im Zeichnungslayer
      ellipse = ID_find_ellips_with_attr (id_prim)
 
      if ellipse = 0 then
         /* Erzeugen und Benennen des Elementes */
         ellipse = ellips_angle2lengths  ( VAR_ID_global_Z, { str1 dick}, p1, r1, r2, r3)
         ID_cre_id_attr ( ellipse, id_view, id_prim )
       else 
         if VAR_ID_global_LineStyle = 0 then
            edit ( ellipse , , { str1 dick} , p1, r1, r2, r3 )
         else
            edit ( ellipse , ,  , p1, r1, r2, r3 )
         end
         ID_undo_delete(ellipse)
      end
    end           

   return (ellipse)

end

// ============================================================

function ID_create_ellipse_arc(id_view, id_prim, elayer, str1,
      p1, p2, p3, r1, r2, r3)
   // Bogen sind aus Splines durch Umrechnung entstanden
   // p1: Mittelpunkt
   // p2: Lagepunkt1
   // p3: Lagepunkt2
   // r1: Angle
   // r2: major radius
   // r3: minor radius
   // 
   ellipse = 0   /* temporaere Ellipse */
   arc = 0       /* zu erzeugender Bogen */
   dick = 3   // Linienstaerke dick  

   switch str1 
      case "solid":      dick = 0.5
      case "dashed":     dick = 0.35
      case "dashdotted": dick = 0.25
   end  

   if id_prim = 0 then
       ellipse = ellips_angle2lengths  ( VAR_ID_global_Z, { str1 dick}, p1, r1, r2, r3)
       if not valid(ellipse) then
          return(0)
       end
       ID_cre_id_attr_spline ( ellipse, id_view, -777 )
       delete (ellipse)
       arc = ellips_arc2points   ( VAR_ID_global_Z, { str1 dick}, ellipse, p2, p3)
       delete (arc)
   else
      // Suchen des Elementes im Zeichnungslayer
      arc = ID_find_spline_with_attr (id_prim, "ellips")
 
      if arc = 0 then
         /* Erzeugen und Benennen des Elementes */
         ellipse = ellips_angle2lengths  ( VAR_ID_global_Z, { str1 dick}, p1, r1, r2, r3)
         if not valid(ellipse) then
            return(0)
         end
         ID_cre_id_attr_spline ( ellipse, id_view, -777 )
         delete (ellipse)
         arc = ellips_arc2points   ( VAR_ID_global_Z, { str1 dick}, ellipse, p2, p3)
         ID_cre_id_attr_spline ( arc, id_view, id_prim )
      else 
         ellipse = arc.par_e
         if VAR_ID_global_LineStyle = 0 then
            edit ( ellipse , , { str1 dick} , p1, r1, r2, r3 )
            edit ( arc ,  , { str1 dick} , ellipse , p2 , p3  )
         else
            edit ( ellipse , ,  , p1, r1, r2, r3 )
            edit ( arc ,  , , ellipse , p2 , p3  )
         end
         ID_undo_delete(arc)
      end
   end           

   return (arc)

end
// ============================================================

function ID_create_spline(id_view, id_prim, fname, 
           elayer, str1, iorder, grp)

// function: create spline
// input
//   id_view, id_prim   int identifier
//   fname      "spline_nonper_urbs" / "spline_periodic_urbs"
//   elayer   int  number of layer
//   iorder   int order of spline
//   grp      group of points
// remarks:
//   some splines are transferred as arcs

   spline = 0   /* zu erzeugender neuer Bogen */
   dick = 3   // Linienstaerke dick  
   switch str1 
      case "solid":      dick = 0.5
      case "dashed":     dick = 0.35
      case "dashdotted": dick = 0.25
   end  

   if id_prim = 0 then
      if fname = "spline_nonper_urbs" then
         spline = spline_nonper_urbs  ( VAR_ID_global_Z, { str1, dick }, 3 , grp )
      else     /* spline_periodic_urbs */
         spline = spline_periodic_urbs  ( VAR_ID_global_Z, { str1, dick }, 3 , grp )
      end
      delete (spline)
   else
      // Suchen des Elementes im Zeichnungslayer
      spline = ID_find_spline_with_attr (id_prim, "spline")
 
      if spline = 0 then
         /* Erzeugen und Benennen */
         if fname = "spline_nonper_urbs" then
            spline = spline_nonper_urbs  ( VAR_ID_global_Z, { str1, dick }, iorder, grp )
         else
            /* spline_periodic_urbs */
            spline = spline_periodic_urbs  ( VAR_ID_global_Z, { str1, dick }, iorder, grp )
         end
         ID_cre_id_attr_spline ( spline, id_view, id_prim )
      else 
         edit ( spline , , , iorder, grp)
         ID_undo_delete(spline)
      end
   end
   return (spline)

end

// ============================================================

function ID_create_balloon(id_view, id_prim, elayer,
                           str1, p1, p2, 
                           ID_FONT, ID_ITALIC, ID_MODUS, height)
  // input
  //   id_view   int     identifier of active view
  //   id_prim   int     identifier of primitive
  //   elayer    int     I-DEAS element layer
  //   str1      string  position number
  //   p1        point   starting point
  //   p2        point   screen position
  //   height    double  heigth of str1

  leng = posball_onpoint (p2)
  if VAR_ID_symbol_old = 0 then
    elem  = symbol_balloon (ID_FONT, ID_ITALIC, ID_MODUS, height,
                           { { 1, 0 }, "bal_circle" },
                           str1, "", "", { } , p1, leng )
    /* No BOM attributes     { { "$_Version", "1" } }
    ID_creatt_user_attrib ( elem , "$_Version" , "\"\"" )
    ID_creatt_user_attrib ( elem , "$_Unit" , "\"\"" )
    ID_creatt_user_attrib ( elem , "$_Name" , "\"\"" )
    ID_creatt_user_attrib ( elem , "$_Material" , "\"\"" )
    ID_creatt_user_attrib ( elem , "$_Stock_number" , "\"\"" )
    ID_creatt_user_attrib ( elem , "$_Remark" , "\"\"" )
    ID_creatt_user_attrib ( elem , "$_Supplier" , "\"\"" )
    ID_creatt_user_attrib ( elem , "$_Mass" , "\"\"" )
    ID_creatt_user_attrib ( elem , "$_Mass_unit" , "\"\"" )
    ID_creatt_user_attrib ( elem , "$_Remark_2" , "\"\"" )
    */

    // attach attributes and move to layer
    itype = 4
    ID_cre_id_attr_textsymbol (elem,itype,id_view,id_prim)   

  else
     elem = VAR_ID_symbol_old
     edit (elem, ID_FONT, ID_ITALIC, ID_MODUS, height,
                 { { 1, 0 }, "bal_circle" },
                 str1, "", "", { } , p1, leng )
      if elem.deleted then 
         undo_delete(elem)
      end
  end
  return (elem)
end

// ============================================================
function ID_edit_balloon( p, str )
// function: edit ballon
// input
//   p  point: part point
//   str    string: position number of balloon

   if valid (VAR_ID_symbol_old) then
      edit (VAR_ID_symbol_old, , , , , , str, , , { } , p,  )
   else
      move_set_to_layer ( { VAR_ID_symbol_old } , 
                            VAR_ID_global_layer_error)
      ID_error_message ( 1, VAR_ID_symbol_old, 
                    VAR_ID_symbol_old.user_viewid,
                    VAR_ID_symbol_old.user_timid )
   end
   VAR_ID_symbol_old = 0
   return
end

// ============================================================
function ID_create_comment ( ID_FONT, ID_ITALIC, ID_MODUS, height, 
                             arrowtyp, angle, str, p1, p2, p3,
                             p4, id_view, id_prim )
// function: create symbol "comment"
// input 
//   ID_FONT, ID_ITALIC, ID_MODUS, height: text font description
//   arrowtyp  "point" / "triangle" / "arrow" 
//   angle angle               
//   str   string    text
//   p1    point     start point of leader line
//   p2    point     bend point
//   p3    point     end point
//   p4    point     text placement point
//
// description:
//    get the old symbol
//    create, when not exist or when old symbol is deleted
//    return: symbol "comment" 
//            or null if old symbol is edited
   elem = 0
   w = coord_onpoint(p4)
   VAR_ID_symbol_old = 
       ID_find_symbol_with_attr (id_view, id_prim)
   if VAR_ID_symbol_old = 0 then
      elem = symbol_comment (ID_FONT, ID_ITALIC, ID_MODUS, height,
             arrowtyp, angle, str, p1, 0, p2, p3, w )
   else
     elem = VAR_ID_symbol_old
     if VAR_ID_global_TextModify = 0 then
        // was deleted at the beginning: keep the layer
        if elem.def_type = "comment" then 
           edit (elem, ID_FONT, ID_ITALIC, ID_MODUS, height,
                 arrowtyp, angle, str, p1, 0, p2, p3, w )
        else // delete old one and create them new 
            delete (elem)
            elem = symbol_comment (ID_FONT, ID_ITALIC, ID_MODUS, height,
                   arrowtyp, angle, str, p1, 0, p2, p3, w )
        end
     end
     if elem.deleted then
       undo_delete(elem)
     end
   end

   return(elem)
 end

// ============================================================
function ID_text_block ( ID_FONT, ID_ITALIC, ID_MODUS, height,
                 textpos_enu, p1 , txtgrp, angle, id_view, id_prim )

// function : create text_block
// input
//    ID_FONT, ID_ITALIC, ID_MODUS, height: Font description
//    textpos_enu  "beginv"  ...  only textblock
//                 "middlem" ...  textblock with comment
//    p1 = point       position of text
//    txtgrp = { "line1", "line2" } text 
//    angle = angle       text angle (inclinination to x-axis)
//    id_view = int    view identifier
//    id_prim = int    object identifier
// return : text

  elem = 0
  lh = ID_create_texttext_height (height)
  if VAR_ID_text_old = 0 then
 
    elem = text_block ( ID_FONT, ID_ITALIC, ID_MODUS, 
            "mnone", textpos_enu,  p1,  txtgrp, lh, angle )
    // attach attributes and move to layer
    itype = 3
    ID_cre_id_attr_textsymbol (elem,itype,id_view,id_prim)
  else
    elem = VAR_ID_text_old
    edit ( elem,  ID_FONT, ID_ITALIC, ID_MODUS,  
            "mnone", textpos_enu,  p1,  txtgrp, lh, angle )
    if elem.deleted then
       undo_delete(elem)
    end
  end
  return (elem)
end

// ============================================================
function ID_edit_text_block ( txt )
// edit text_block
//   consists of symbol "comment" (sometimes)
//   and text block

   iError = 1
   if VAR_ID_text_old.def_type = "block" then
      edit ( VAR_ID_text_old , , , , , , , txt, , )
      iError = 0
   end
 
   if iError = 1 then
      layer_move_objects ( { VAR_ID_text_old } , 
                            VAR_ID_global_layer_error)
      ID_error_message ( 1, VAR_ID_text_old, 
                    VAR_ID_text_old.user_viewid,
                    VAR_ID_text_old.user_timid )
   else
      // get the symbol and take it from the list
      // otherwise it would be deleted at the end
      symbol_old = ID_find_symbol_with_attr
                 (VAR_ID_text_old.user_viewid, 
                  VAR_ID_text_old.user_timid)
   end
   VAR_ID_text_old = 0
   VAR_ID_symbol_old = 0
end

// ============================================================
function ID_edit_comment ( str, p1 )
// edit symbol comment
//   str   string   text
//   p1    point    start point of symbol
   elem = VAR_ID_symbol_old
   if elem.def_type = "comment" then 
      edit (elem, , , , ,
            , , str, p1, , , , )
   end
end

// ============================================================
function ID_symbol_reference ( ID_FONT, ID_ITALIC, modus, height,
         val, start, bend, frame, id_view, id_prim)
// function: create symbol reference
// input paramaters
//   ID_FONT, ID_ITALIC, modus, height: Font description
//   val         : string              
//   start       : point               
//   bend        : point               
//   frame       : point  --> wcoord                  
//   id_view     : int  view identifier from IDEAS
//   id_prim     : int  primitive identifier from IDEAS
// return: symbol

  elem = 0
  w = coord_onpoint(frame)
  if VAR_ID_symbol_old = 0 then
     elem = symbol_reference ( ID_FONT, ID_ITALIC, modus, height, 
                               val, start, bend, w )          
     // attach attributes and move to layer
     itype = 4
     ID_cre_id_attr_textsymbol (elem,itype,id_view,id_prim)   
  else
     elem = VAR_ID_symbol_old
     edit (elem,  ID_FONT, ID_ITALIC, modus, height, 
                  val, start, bend, w )
     if elem.deleted then
        undo_delete(elem)
     end
  end
  return (elem)
end

// ============================================================

function ID_symbol_form ( ID_FONT, ID_ITALIC, modus, height,
     symb, val, gstring, start, bend, frame, id_view, id_prim)
           
// function: create symbol form
// input paramaters
//   ID_FONT, ID_ITALIC, modus, height: Font description
//   symb        : tolsymbolrec        
//   val         : string              
//   gstring     : group of strings (Reference character)            
//   start       : point               
//   bend        : point               
//   frame       : point  --> wcoord                  
//   id_view     : int  view identifier from IDEAS
//   id_prim     : int  primitive identifier from IDEAS
// return: symbol

  elem = 0
  w = coord_onpoint(frame)
  if VAR_ID_symbol_old = 0 then
     elem = symbol_form ( ID_FONT, ID_ITALIC, modus, height,
                          symb, val, gstring, start, bend, w)
     // attach attributes and move to layer
     itype = 4
     ID_cre_id_attr_textsymbol (elem,itype,id_view,id_prim)   
  else
     elem = VAR_ID_symbol_old
     edit (elem, ID_FONT, ID_ITALIC, modus, height, 
                 symb, val, gstring, start, bend, w)
     if elem.deleted then
        undo_delete(elem)
     end
  end
  return (elem)
end


// ============================================================
function ID_string_absolute (str)
   string =  string_absolute (  str  )
   return (string) 
end

// ============================================================
function ID_header_set()
   return
end

// ============================================================
function ID_undo_delete ( ele )
   if ( VAR_ID_KeepDelete = 0 and ele.deleted and 
        not (ele in VAR_ID_global_grp_invis) ) then
      undo_delete(ele)
   end
   return
end

// ============================================================
function ID_transfer_end()
   // top layer aktiv setzen und Zeichnungslayers sperren 

//   update_mode (true)   
   redraw_event ()
   prompt(ID_TXT_UpdateEnd)


   // "work around" 
   // Error in Design: when deleting elliptical arc --> ellipse is undeleted
   //        ellipse, id_view, -777 --> delete            
   del_grp = VAR_ID_global_layer.list_ellips where (.user_niden = -777 and not .deleted)
   if not empty(del_grp) then
      delete(del_grp)
   end

   // Loeschen der nicht uebertragenen Texte, Symbole und Masse
   if VAR_ID_global_TextModify > 0 and len(VAR_ID_global_grp_text) > 0 then
         delete(VAR_ID_global_grp_text)
   end   
   if VAR_ID_global_SymbolModify > 0 then
      if len(VAR_ID_global_grp_plane) > 0 then
         delete(VAR_ID_global_grp_plane)
      end   
      if len(VAR_ID_global_grp_symbol) > 0 then
         delete(VAR_ID_global_grp_symbol)
      end   
   end   
   if len(VAR_ID_global_grp_mass) > 0 then
      delete(VAR_ID_global_grp_mass)
   end   

   // Suchen ob sich im Layer "error" Elemente befinden
   grp1 = VAR_ID_global_layer_error.list_all where not .deleted 
       and valid (.prim_type)
   grp = grp1 where  .prim_type != "world"
   if not empty(grp) then
      // Alle Elemente farbig darstellen
      color (  VAR_ID_global_layer_error ,  VAR_color_error_layer )
      display_error(ID_TXT_ReferToDelPrims)
   end

   // Save model when IPC with I-DEAS
   if (VAR_ID_global_Model_Save) then  
      if ID_DEBUG then
         `save ` [VAR_ID_global_TopFname] nl
      end
      model_save (model(), true, false, VAR_ID_global_TopFname  )
   end

   file "/dev/null" error_output 
   file VAR_ID_global_error_file input
   str = parse_line()
   if valid(str) then
      file VAR_ID_global_error_file output
      [ID_TXT_ModelName] ` ` [VAR_ID_global_TopFname] nl
      [date()] nl
      file <screen>    // Ruecksetzen auf Standardausgabe
      [ID_TXT_Errorfile] [VAR_ID_global_error_file] nl 
    else
      system ( "rm " + VAR_ID_global_error_file)
    end

   /* Grafik und Reevalueriung einschalten */
   if ID_DATE_OUTPUT then
      `transfer_end : ` [date()] nl 
   end

   if top.status != "active" then
      edit (top ,  , "active" , false  )
   end  
   if VAR_ID_global_locked_layer then
      edit (VAR_ID_global_layer, , "selectable", true)
      edit (VAR_ID_global_layer_key, , "selectable", true)
      edit (VAR_ID_global_layer_draw, , "selectable", true)
      edit (VAR_ID_global_layer_make_up, , "selectable", true)
   else
      edit (VAR_ID_global_layer, , "selectable", false)
      edit (VAR_ID_global_layer_key, , "selectable", false)
      edit (VAR_ID_global_layer_draw, , "selectable", false)
      edit (VAR_ID_global_layer_make_up, , "selectable", false)
   end

 end

// ============================================================

function ID_error_message ( faultnr, ele, id_view, id_prim )

  // error messages to error file

  file VAR_ID_global_error_file output

  switch faultnr 
    case 1:
      // ID_TXT_Fault10 = "Fehler beim Editieren von "
      // ID_TXT_Fault11 = "Element liegt auf Ebene "
      // ID_TXT_Fault12 = "Beim nochmaligen Uebergang wird
      //              Originalzustand wieder hergestellt."
      [ID_TXT_Fault10] [ele.prim_type] ` ` [id_view] ` ` [id_prim] nl
      [ID_TXT_Fault11] [VAR_ID_global_layer_error.name] nl
      [ID_TXT_Fault12] nl
    case 2:
      // ID_TXT_Fault20 = "Error: Non uniform layer name. Layer "
      // ID_TXT_Fault21 = "    exists "
      // ID_TXT_Fault22 = " times. First layer was updated."
      [ID_TXT_Fault20] [ele.name] nl
      [ID_TXT_Fault21] [id_view] [ID_TXT_Fault22] nl
    case 3:
      // ID_TXT_Fault30 = "Warning: size of title block approximated "
      [ID_TXT_Fault30] nl
      [ele] nl
      [id_view] nl

  end
  file <screen>    // Ruecksetzen auf Standardausgabe

  return
end

// ============================================================

function ID_hatch_loop()

  // Loeschen der Punkte der Kontur und zuruecksetzen der Liste.
  // Innerhalb dieser Liste werden Punkte ueber "search" gefangen 
  // um Genauigkeitsprobleme zu umgehen.

  if len(VAR_ID_global_grp_ptshat) > 0 then
     if ID_DEBUG then
        `Error in  ID_hatch_loop: creating plane len = ` 
        [len(VAR_ID_global_grp_ptshat)]  nl
        for i in VAR_ID_global_grp_ptshat do
            `point ` [i.par_dx.norm] `  `  [i.par_dy.norm] nl
        end
     end
     delete ( VAR_ID_global_grp_ptshat )
     VAR_ID_global_grp_ptshat = {}
   end
  return (1)
end

// ============================================================

function ID_get_model_file()

// get Design Model File
//     load or create when actice model = "std"
// <IDEAS model_file>_<IDEAS layer name>

   active_model = model()
   if ( active_model.name != "std" ) then
      return
   end

   // add info of part to model_file name
   // name_part = VAR_ID_global_MFname + "_" + VAR_ID_global_PartNo +
   //                                    "_" + VAR_ID_global_Ver +
   //                                    "_" + VAR_ID_global_Rev

   // name_part =  VAR_ID_global_MFname + "_" + VAR_ID_global_name_ideas 
      name_part =  VAR_ID_global_MFname + "_" + VAR_ID_global_name_ideas 
      model_file = name_part + ".mod"

   // max 28 characters
   // if (len(model_file) >28) then
   //    model_file = substr ( model_file, 1, 28)
   //    display_error(ID_TXT_CutNameModel28Char + model_file + "%")
   // end

      dir_part = ""  /* directory of model file */
      ve_home_dir = getenv("HOME")
      dir_part = ve_home_dir + "/ideas_ve_daten"

   model_file = popup_filename( ID_TXT_ModelName, "*.mod", dir_part, model_file, "o")
   if not valid(model_file) then
      return
   end

   name_part = ID_simple_name (model_file)
   if (name_part = "std") then
      return
   end
   m = "" 
   // IDM-Infos vom Layout ans VE-Model - first_world - anhaengen 
   // load or create IDM-model file
   if existf( model_file ) then 
     if ID_DEBUG then
        `load model from file ` [model_file] nl 
     end
     model_load (model_file, false)
     m = model (name_part)
   else
     if ID_DEBUG then
           `create model ` [name_part] nl 
     end
     model_create (name_part)
     m = model (name_part)
   end

     //
     // Attribute werden an die first_world gehaengt und mit Wert versehen 
     // ProjectName    : VAR_ID_global_Pjname
     // ModelName      : VAR_ID_global_MFname
     // LayoutName     : VAR_ID_global_name_ideas
     // PartNumber     : VAR_ID_global_PartNo
     // VersionNumber  : VAR_ID_global_Ver
     // RevisionNumber : VAR_ID_global_Rev
     //
     if valid(first_world) then

        if valid (first_world.user_ProjectName) then
                      // Objekt     Attributname      Attributwert
           set_attrib (first_world, "ProjectName", VAR_ID_global_Pjname)
        else
           create_attrib (first_world, "ProjectName", VAR_ID_global_Pjname)
        end
        if valid (first_world.user_ModelName) then
           set_attrib (first_world, "ModelName", VAR_ID_global_MFname)
        else
           create_attrib (first_world, "ModelName", VAR_ID_global_MFname)
        end
        if valid (first_world.user_LayoutName) then
           set_attrib (first_world, "LayoutName",    VAR_ID_global_name_ideas)
        else
           create_attrib (first_world, "LayoutName", VAR_ID_global_name_ideas)
        end
        if valid (first_world.user_PartNumber) then
           set_attrib (first_world, "PartNumber",     VAR_ID_global_PartNo)
        else
           create_attrib (first_world, "PartNumber",     VAR_ID_global_PartNo)
        end
        if valid (first_world.user_VersionNumber) then
           set_attrib (first_world, "VersionNumber",  VAR_ID_global_Ver)
        else
           create_attrib (first_world, "VersionNumber",  VAR_ID_global_Ver)
        end
//        if valid (first_world.user_RevisionNumber) then
//           set_attrib (first_world, "RevisionNumber", VAR_ID_global_Rev)
//        else
//           create_attrib (first_world, "RevisionNumber", VAR_ID_global_Rev)
//        end

     end


// close the std model and view
   mc = model_close (  model ("std"), false, false, "./" )
   view_set (id ("programmed action", m, mc, 0))
   va = view_absolute (id ("programmed object", m, mc, 0))
   grp = top.list_view where .active = true
   v = grp.first
   d1 = ( v.left_top.x + v.right_bottom.x ) / 2
   d2 = ( v.left_top.y + v.right_bottom.y ) / 2
   viewport_close ({ v, int(d1), int(d2), v, int(d1), int(d2) })

   VAR_ID_global_TopFname = model_file
   VAR_ID_global_Model_Save = true

   return
end

// ============================================================

function ID_get_model_info()

// get information from file "idminfo.3d2d"
// part number, version and revision

   filename = "idminfo.3d2d"
   if not file_access ( filename, "r" ) then
      display_error ( translate_message(run_err_no_read_access, filename) )
   end
   file filename input
   h = ""
   n = 1
   while valid( h ) AND n <= 13 do
      parse_comment()
      h = parse_line()
      if n > 12 then
         str = substr(h,71,102)
         i = len( str )
         while i > 0 and substr(str, i, i) = " " do
            i = i - 1
         end
         if i > 0 then
            VAR_ID_global_PartNo = substr(str, 1, i)
         else
            VAR_ID_global_PartNo = ""
         end
         // wegen Fehler aus IDEAS MS30 -> wenn deutsch Oberflaeche
         if VAR_ID_global_PartNo = "?" then
            VAR_ID_global_PartNo = ""
         end

         str = substr(h,106,108)
         i = len( str )
         while i > 0 and substr(str, i, i) = " " do
            i = i - 1
         end
         if i > 0 then
            VAR_ID_global_Ver = substr(str, 1, i)
         else
            VAR_ID_global_Ver = ""
         end

//         str = substr(h,82,84)
//         i = len( str )
//         while i > 0 and substr(str, i, i) = " " do
//            i = i - 1
//         end
//         if i > 0 then
//            VAR_ID_global_Rev = substr(str, 1, i)
//         else
//            VAR_ID_global_Rev = ""
//         end
         
      end
      n = n + 1
   end
   close()

   return
end

// ============================================================

