include #/d2drw/msc/mess.lan

VAR_epsilon    = 0.0005               // 0.033 fuer grosse Modelle
VAR_hidden     = false                // hidden Objecte mit erzeugen
VAR_askhid     = false                // Abfrage fuer hidden Objecte erfolgt

VARUpdViewPos  = false // Viewposition aendern erlaubt
VARUpdMeasPos  = false // Massposition aendern erlaubt

VARViewOrig    = 0    // Ursprung der aktuellen world
VARViewWorld   = 0
VARViewRep     = ""
VARLayoutOrig  = 0
VARLayoutWorld = 0
VARLayoutName  = " "

VARLayerTop    = 0
VARLayerHidden = 0
VARLayerKey    = 0
VARLayerMakeUp = 0
VARLayerDraw   = 0
VARLayerError  = 0
VARLayerInvis  = 0

VARPartId      = ""
VARFeatureId   = ""
VARParName     = ""
VARParFormula  = ""

GROUPObjects   = {}
GROUPPoint     = {}
GROUPLine      = {}
GROUPCircle    = {}
GROUPEllips    = {}
GROUPSpline    = {}
GROUPContour   = {}
GROUPDimention = {}
GROUPPlane     = {}
GROUPText      = {}
GROUPSymbol    = {}
GROUPInvis     = {}

GROUPEditPoint = {}

VARColorErrorLayer = 50

VAR_RefSpline  = invalid   // Referenzspline fuer Splinesegmente

VAR_EUKLID     = false

// ************************************************************
//                Funktionsdedeklaration forward
// ============================================================
function CreateUserAttrib     (obj, att, val) forward
function CreateIdAttr         ( elem, view_id, elem_id ) forward
function CreateMeasInfoAttr   ( elem ) forward
function FindObject           ( att, val, obj_group ) forward
function DeleteObject         ( elem ) forward
function MoveToLayer          ( elem, visib ) forward
function ModelStart           ( lname ) forward
function TransferEnd          () forward
function CreateLayerStruct    () forward
function CreateLayer          ( lname, status ) forward
function DeleteLayer          () forward
function CreateHead           ( version, name, date, user, comment ) forward
function CreateLayoutWorld    () forward
function CheckDeleteLayoutWorld () forward
function GetViewObjects       ( view_id ) forward
function CreateView           ( view_id, wname, rep, posx, posy, angle, scale ) forward
function CreatePoint          ( view_id, dx, dy, addgrp ) forward
function EditPoint            ( elem, dx, dy, addgrp ) forward
function DeletePoint          ( elem ) forward
function CreateLine           ( view_id, edge_id, elem_id, visib, style, limited, sp, ep ) forward
function DeleteLine           ( elem_id ) forward
function CreateCircle         ( view_id, edge_id, elem_id, visib, style, axis, center, radius ) forward
function CreateCircleArc      ( view_id, edge_id, elem_id, visib, style, axis, center, sp, ep ) forward
function DeleteCircle         ( elem_id ) forward
function CreateEllips         ( view_id, edge_id, elem_id, visib, style, axis, center, angle, maj_rad, min_rad ) forward
function CreateEllipsArc      ( view_id, edge_id, elem_id, visib, style, axis, center, angle, maj_rad, min_rad, sp, ep ) forward
function DeleteEllips         ( elem_id ) forward
function CreateSpline         ( view_id, edge_id, elem_id, visib, style, deg, points, knots ) forward
function CreateSplinePart     ( view_id, edge_id, elem_id, visib, style, deg, points, knots, sp, ep ) forward
function DeleteSpline         ( elem_id ) forward
function CreateContour        ( view_id, cont_id, elem_group ) forward
function DeleteContour        ( elem_id ) forward
function CreatePosttext       ( post ) forward
function EditPosttext         ( elem, post ) forward
function SetMeasureInfo       ( part_id, feature_id, par_name, par_formula ) forward
function CreateMeasureP1P2    ( view_id, elem_id, mtype, control, pre, post, comment, proj, p1, p2, pos ) forward
function CreateMeasureAngle   ( view_id, elem_id, mtype, control, pre, post, comment, p1, p2, p3, pos ) forward
function CreateMeasureDiam    ( view_id, elem_id, mtype, control, pre, post, comment, proj, p1, p2, pos ) forward
function CreateMeasureRad     ( view_id, elem_id, mtype, control, pre, post, comment, cen, rad, pos ) forward
function DeleteMeasure        ( elem_id ) forward
function FindRefElements      ( ref_ids ) forward
function CreatePlane          ( view_id, elem_id, dist, angle, ref_ids ) forward
function DeletePlane          ( elem_id ) forward
function CreateSectionDef     ( view_id, elem_id, name, view_dir, coord1, coord2, sect_p ) forward
function DeleteSectionDef     ( elem_id ) forward
function CreateSectionText    ( view_id, elem_id, name, pos ) forward
function DeleteSectionText    ( elem_id ) forward
function CreateDetailDef      ( view_id, elem_id, name, center, txpos, radius ) forward
function DeleteDetailDef      ( elem_id ) forward
function CreateDetailText     ( view_id, elem_id, name, pos ) forward
function DeleteDetailText     ( elem_id ) forward
function CreateRotLine        ( view_id, elem_id, num, sp1, ep1, sp2, ep2 ) forward
function DeleteRotLine        ( elem_id ) forward



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

function CreateUserAttrib (obj, att, val)
   /*   Erzeugen eines Userattributes am Objekt              */
   /*                                                        */
   /*   Eingabe:                                             */
   /*      obj       : Objekt                                */
   /*      att       : Attributname                          */
   /*      val       : Attributwert                          */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   if not VAR_EUKLID then
      if valid ( obj.["user_" + att] ) then
         set_attrib ( obj, att, val )  
      else
         create_attrib (obj, att, val ) 
      end 
   end

end

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

function CreateIdAttr ( elem, view_id, elem_id )
   /*   Anhaengen der Identifikatoren an die Elemente        */
   /*   Eingabe:                                             */
   /*      elem      : Objekt                                */
   /*      view_id   : Attributwert fuer Attr. "ViewId"      */
   /*      elem_id   : Attributwert fuer Attr. "ElemId"      */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */
 
   CreateUserAttrib (elem, "ViewId", view_id) 
   CreateUserAttrib (elem, "ElemId", elem_id)

end

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

function CreateMeasInfoAttr  ( elem )
   /*   Anhaengen der Massinformation                        */
   /*   Eingabe:                                             */
   /*      elem      : Objekt                                */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   CreateUserAttrib (elem, "PartId"    , VARPartId)
   CreateUserAttrib (elem, "FeatureId" , VARFeatureId)
   CreateUserAttrib (elem, "ParName"   , VARParName)
   CreateUserAttrib (elem, "ParFormula", VARParFormula)

end

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

function FindObject ( att, val, var obj_group )
   /*   Finden eines Objektes in einer Gruppe                */
   /*   Eingabe:                                             */
   /*      att       : Attributname                          */
   /*      val       : Attributwert fuer Attr. att           */
   /*      obj_group : Gruppe mit Objekten                   */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Gefundenes Objekt                                 */
   
   elem = 0
   if not VAR_EUKLID then
      if not empty(obj_group) then
         Group = obj_group where .["user_" + att] = val
         if not empty(Group) then
            elem = Group.first
         end
      end
   end
   return (elem)

end

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

function DeleteRefObject ( elem )
   /*   Loeschen des Referenzobjektes von Ellipsenbogen      */
   /*   und Splinestueck                                     */
   /*   Eingabe:                                             */
   /*      elem      : Objekt                                */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */
   
   if elem.type.name = "ellips" then
      if elem.created_by.type.name = "ellips_arc2points" then
         delete(elem.created_by.par_e)
      end
   end
   if elem.type.name = "spline" then
      if elem.created_by.type.name = "spline_cutonpoints" then
         delete(elem.created_by.par_sp)
      end
   end

end

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

function DeleteObject         ( elem )
   /*   Loeschen eine Objektes                               */
   /*   Eingabe:                                             */
   /*      elem      : Objekt                                */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */
   
   layer_move_objects ({elem}, VARLayerError)
   layer_move_objects (elem.allsons, VARLayerError)
   delete_attrib(elem, "ViewId")
   delete_attrib(elem, "EdgeId")
   delete_attrib(elem, "ElemId")
   delete(elem)
   Group = elem.created_by.list_effects where not .deleted
   if not empty(Group) then
      delete(Group)
   end
   DeleteRefObject(elem)

end

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

function MoveToLayer ( elem, visib )
   /*   Verschieben eines Objektes in einen Layer            */
   /*   Eingabe:                                             */
   /*      elem      : Objekt                                */
   /*      visib     : Sichtbarkeitsstatus des Objects       */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */
   
   if visib = "hidden" then
      layer_move_objects ({elem}, VARLayerHidden)
      if VARViewRep = "hidden" then
         delete(elem)
         DeleteRefObject(elem)
      end
   end
   if visib = "occluded" then
      layer_move_objects ({elem}, VARLayerInvis)
      delete(elem)
      DeleteRefObject(elem)
   end
   if visib = "visible" and ( elem.layer = VARLayerHidden or
                              elem.layer = VARLayerInvis ) then
      undo_delete(elem)
      layer_move_objects ({elem}, VARLayerTop)
   end

end

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

function ModelStart ( lname )
   /*   Vorbereitende Aktionen                               */
   /*   Eingabe:                                             */
   /*      lname   : Layout Name                             */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   VARLayoutName = lname
   CreateLayerStruct ()
   CreateLayoutWorld ()
end

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

function TransferEnd ()
   /*   Abschliessende Aktionen                              */
   /*   Eingabe:                                             */
   /*      ---                                               */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   // Alle nicht mehr benutzten Punkte loeschen
   if not VAR_EUKLID then
      for i in top.list_point where valid(.user_ViewId) do
         DeletePoint(i)
      end
   end

   // Suchen ob sich im Layer "error" Elemente befinden
   if not VAR_EUKLID then
      Group = VARLayerError.list_all where not .deleted and valid (.prim_type) and
                                           .prim_type != "world"
      if not empty(Group) then
         // Alle Elemente farbig darstellen
         color (VARLayerError, VARColorErrorLayer)
      end
   end

   // Top Layer aktiv setzen und Zeichnungslayers sperren 
   if top.status != "active" then
      edit (top ,  , "active" , false  )
   end  
   if not VAR_EUKLID then
      edit (VARLayerTop,    , "selectable", true)
      edit (VARLayerHidden, , "selectable", true)
      edit (VARLayerKey,    , "selectable", true)
      edit (VARLayerMakeUp, , "selectable", true)
      edit (VARLayerDraw,   , "selectable", true)
   end

   prompt( translate_message(d2t32_inf_end_update) )

   // Grafik und Reevalueriung einschalten
//   update_mode (true)   
   redraw_event ()

   file <screen>

end

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

function CreateLayerStruct ()
   /*   Erzeugen einer Layer Struktur                        */
   /*   Eingabe:                                             */
   /*      ---                                               */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   // Top Layer aktiv setzen
   if top.status != "active" then
      edit ( top , ,"visible", false)
      edit ( top , ,"active" , false)
   end

   // Erzeugen oder editieren der Sublayer
   VARLayerTop     = CreateLayer ( VARLayoutName  , "active" )
   if not VAR_EUKLID then
      VARLayerHidden  = CreateLayer ( VARLayoutName + "_hidden"  , "selectable" )
      VARLayerKey     = CreateLayer ( VARLayoutName + "_key"     , "selectable" )
      VARLayerMakeUp  = CreateLayer ( VARLayoutName + "_make_up" , "selectable" )
      VARLayerDraw    = CreateLayer ( VARLayoutName + "_draw"    , "selectable" )
      VARLayerError   = CreateLayer ( VARLayoutName + "_error"   , "selectable" )
      VARLayerInvis   = CreateLayer ( VARLayoutName + "_invis"   , "inactive" )
   end

   if not VAR_EUKLID then
      // Alle uebertragenen Mass in den Layern "_key", "_make_up" und "_invis" aufsammeln
      GROUPDimention  = VARLayerKey.list_measure where valid(.user_ElemId) and not .deleted
      GROUPDimention  = ( VARLayerMakeUp.list_measure where valid(.user_ElemId) and not .deleted )
                        + GROUPDimention
      GROUPDimention  = ( VARLayerInvis.list_measure where valid(.user_ElemId) and not .deleted )
                        + GROUPDimention

      // Alle uebertragenen Texte, Symbole und Planes in den Layern "_make_up" und "_invis" aufsammeln
      Group           = VARLayerMakeUp.list_all where valid(.user_ElemId) and not .deleted
      GROUPPlane      = Group where .type.name = "plane"
      GROUPText       = Group where .type.name = "text"
      GROUPSymbol     = Group where .type.name = "symbol"
      Group           = VARLayerInvis.list_all where valid(.user_ElemId) and not .deleted
      GROUPPlane      = ( Group where .type.name = "plane"  )
                        + GROUPPlane
      GROUPText       = ( Group where .type.name = "text"   )
                        + GROUPText
      GROUPSymbol     = ( Group where .type.name = "symbol" )
                        + GROUPSymbol
   end

end

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

function CreateLayer ( lname, status )
   /*   Erzeugen eines Layers                                */
   /*   Eingabe:                                             */
   /*      lname   : Layer Name                              */
   /*      status  : status des Layers                       */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Layer                                             */

   Layer = 0
   if not VAR_EUKLID then
      LayerGroup = top.list_layer where .name = lname
   else
      LayerGroup = {}
   end

   if empty(LayerGroup) then
      Layer = layer_normal ( lname , status , false  ) 
      // Attribut mit Layernamen vergeben
      if not VAR_EUKLID then
         set_attrib (Layer, "LName", lname)
      end
   else
      if len(LayerGroup) > 1 then
         Group = LayerGroup where .user_lname = lname
         if len(Group) = 1 then
            Layer = Group.first
         else
            // Error
            `Error1 CreateLayer` nl
            Layer = LayerGroup.first
         end
      else 
         Layer = LayerGroup.first
      end

      // setze Layer auf nicht geloescht
      if Layer.deleted then
         undo_delete(Layer)
         // Attribut mit Layernamen vergeben
         set_attrib (Layer, "LName", lname)
      end

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

  if len(LayerGroup) > 1 then
     `Error2 CreateLayer` nl
  end
  return (Layer)
end

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

function DeleteLayer ()
   /*   Layer loeschen                                       */
   /*   Eingabe:                                             */
   /*      ---                                               */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   delete_attrib( VARLayerTop,    "LName")
   delete_attrib( VARLayerHidden, "LName")
   delete_attrib( VARLayerKey,    "LName")
   delete_attrib( VARLayerMakeUp, "LName")
   delete_attrib( VARLayerDraw,   "LName")
   delete_attrib( VARLayerError,  "LName")
   delete_attrib( VARLayerInvis,  "LName")

   if not VARLayerTop.deleted then
      layer_delete( VARLayerTop,    "delete" )
   end
   if not VARLayerHidden.deleted then
      layer_delete( VARLayerHidden, "delete" )
   end
   if not VARLayerKey.deleted then
      layer_delete( VARLayerKey,    "delete" )
   end
   if not VARLayerMakeUp.deleted then
      layer_delete( VARLayerMakeUp, "delete" )
   end
   if not VARLayerDraw.deleted then
      layer_delete( VARLayerDraw,   "delete" )
   end
   if not VARLayerError.deleted then
      layer_delete( VARLayerError,  "delete" )
   end
   if not VARLayerInvis.deleted then
      layer_delete( VARLayerInvis,  "delete" )
   end

end

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

function CreateHead ( version, name, date, user, comment )
   /*   Head Daten an Globalsobjekt haengen                  */
   /*   Eingabe:                                             */
   /*      version : Version der T32 Schnittstelle           */
   /*      name    : Name                                    */
   /*      date    : Datum der Ausleitung                    */
   /*      user    : Benutzer                                */
   /*      comment : Kommentar                               */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   // Fehlerausgaben in Datei
   file "T32_error" error_output
   file "T32_error" output

   prompt( translate_message(d2t32_inf_begin_update) )

   // Set variable if T32 from SurfaceN
   if name = "SurfaceN" or name = "EUKLID" then
      VAR_EUKLID = true
   end

   // Grafik und Reevalueriung abschalten
//   update_mode (false)

   // Globalsobjekt suchen.
   Group = top.list_globals
   if empty(Group) then
      `Kein Globalsobjekt gefunden` nl
   else
      elem = Group.first
      CreateUserAttrib (elem, "T32Version", version) 
      CreateUserAttrib (elem, "T32Name", name) 
      CreateUserAttrib (elem, "T32Date", date) 
      CreateUserAttrib (elem, "T32User", user) 
      CreateUserAttrib (elem, "T32Comment", comment) 
   end

end

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

function CreateLayoutWorld ()
   /*   Erzeugen oder Aendern einer LayoutWorld              */
   /*   Eingabe:                                             */
   /*      name    : Layout Name                             */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      World                                             */

   // World mit Namen suchen. Wenn keine gefunden, eine erzeugen
   if not VAR_EUKLID then
      Group = top.list_world where .name = VARLayoutName
   else
      Group = {}
   end
   if empty(Group) then 
      elem = world_firstrota ( {0.0, 0.0, 0.0}, 0.0, 1.0)
      name( elem, VARLayoutName )
      VARLayoutWorld = elem
      CreateUserAttrib (elem, "Layout", true) 
   else
      VARLayoutWorld = Group.first
      if VARLayoutWorld.deleted then
         undo_delete(VARLayoutWorld)
      end
   end
   VARLayoutOrig  = VARLayoutWorld.sons.first
end

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

function CheckDeleteLayoutWorld ()
   /*   Pruefen ob Layout World und Layer zu loeschen sind   */
   /*   Eingabe:                                             */
   /*      ---                                               */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   // Layout World mit Namen suchen.
   Group = VARLayoutWorld.allsons where .type.att_drawable and not .deleted
   if empty(Group) or
      ( len(Group) = 1 and Group.first = VARLayoutOrig ) then 
   
      delete(VARLayoutOrig)
      name( VARLayoutWorld, "" )
      delete(VARLayoutWorld)
      pos = VARLayoutWorld.par_pos
      ang = VARLayoutWorld.par_an
      sca = VARLayoutWorld.par_s
      delete(pos)
      delete(ang)
      delete(sca)

      // Loeschen der Sublayer
      DeleteLayer ()
   end
end

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

function GetViewObjects ( view_id )
   /*   Objektgruppen mit Attribut view_id bilden            */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   GROUPObjects = (VARLayerTop.list_all where valid(.user_ViewId) and
                                              .user_ViewId = view_id)
 
   // Objekte soll es nur einmal geben ( auch geloeschte )
   GROUPPoint     = GROUPObjects where .type.name = "point" 
   GROUPLine      = GROUPObjects where .type.name = "line"
   GROUPCircle    = GROUPObjects where .type.name = "circle"
   GROUPEllips    = GROUPObjects where .type.name = "ellips"
   GROUPSpline    = GROUPObjects where .type.name = "spline"
   GROUPContour   = GROUPObjects where .type.name = "contour"

end

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

function CreateView ( view_id, wname, rep, posx, posy, angle, scale )
   /*   Erzeugen oder Aendern einer View                     */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      wname   : Name der World                          */
   /*      posx    : x-Koordinate der World                  */
   /*      posy    : y-Koordinate der World                  */
   /*      angle   : Winkel der World                        */
   /*      scale   : Massstab der World                      */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      World                                             */

   // Setzen des Namens der aktuellen View
   view_name = wname + "_" + VARLayoutName

   // Representation der View
   VARViewRep = rep

   // Abfrage ob verdeckte Kanten erzeugt werden sollen
   if VARViewRep = "hidden" and not VAR_askhid then
      VAR_hidden = not popup_boolean( translate_message(d2t32_inf_create_hidden),
                                      translate_message(d2drw_lab_no),
                                      translate_message(d2drw_lab_yes) )
      VAR_askhid = true
   end

   // World mit Namen suchen. Wenn keine gefunden, eine erzeugen
   if not VAR_EUKLID then
      Group = top.list_world where .name = view_name
   else
      Group = {}
   end

   if empty(Group) then 
      prompt( translate_message(d2t32_inf_create_view) + " \"" + wname + "\"")

      p = point_relative (VARLayoutOrig, posx, posy)
      c = coord_onpoint (p)
      elem = world_firstrota ( c, angle, scale )
      name( elem, view_name )
      CreateUserAttrib (elem, "ViewId", view_id) 
      VARViewOrig  = elem.sons.first
      VARViewWorld = elem
      GROUPPoint = {}
   else
      prompt( translate_message(d2t32_inf_update_view) + " \"" + wname + "\"")

      if len(Group) > 1 then
         Group1 = Group where not .deleted
         if not empty(Group1) then
            VARViewWorld = Group1.first 
         else
            VARViewWorld = Group.first 
         end
      else
         VARViewWorld = Group.first 
         if VARViewWorld.deleted then
            undo_delete(VARViewWorld)
         end
      end

      VARViewOrig = VARViewWorld.sons.first

      // Position, Winkel und Massstab der world aendern
      if VARUpdViewPos then
         pos = VARViewWorld.par_pos.par_p
         if abs(pos.par_dx.norm - posx) > VAR_epsilon or
            abs(pos.par_dy.norm - posy) > VAR_epsilon then
            edit( pos, , posx, posy )
         end
         if abs(VARViewWorld.par_an.norm - angle) > VAR_epsilon or
            abs(VARViewWorld.par_s.norm  - scale) > VAR_epsilon then
            edit (VARViewWorld, , angle, scale)
         end
      end

      // Objekte mit view Attributen ermitteln
      GetViewObjects( view_id )
      GROUPEditPoint = {}
   end

   if not VAR_EUKLID then
      // Alle "hidden" Elemente wieder sichtbar machen wenn unsichtbar und VARViewRep = "hidden_dotted"
      if VARViewRep = "hidden_dotted" then
         Group = VARLayerHidden.list_all where .type.name in {"point", "line", "circle", "ellips", "spline"}
                                           and valid(.user_ViewId) and .user_ViewId = view_id
         for i in Group where .deleted do
            undo_delete(i)
         end
      end
      // Alle "hidden" Elemente wieder unsichtbar machen wenn sichtbar und VARViewRep = "hidden"
      if VARViewRep = "hidden" then
         Group = VARLayerHidden.list_all where .type.name in {"point", "line", "circle", "ellips", "spline"}
                                           and valid(.user_ViewId) and .user_ViewId = view_id
         for i in Group where not .deleted do
            delete(i)
            DeleteRefObject(i)
         end
      end
   end

   return (VARViewWorld)

end

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

function DeleteView ( view_id, wname )
   /*   Loeschen einer View                                  */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      wname   : Name der World                          */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   // Objekte mit view Attributen ermitteln
   GetViewObjects( view_id )

   DeleteGroup = GROUPLine + GROUPCircle + GROUPEllips + GROUPSpline + GROUPContour

   // Alle uebertragenen Mass in den Layern "_key", "_make_up" und "_invis" aufsammeln
   Group = VARLayerKey.list_measure where valid(.user_ViewId) and
                                          .user_ViewId = view_id and
                                          not .deleted
   Group = ( VARLayerMakeUp.list_measure where valid(.user_ViewId) and
                                               .user_ViewId = view_id and
                                               not .deleted ) + Group
   Group = ( VARLayerInvis.list_measure where valid(.user_ViewId) and
                                              .user_ViewId = view_id and
                                              not .deleted ) + Group
   DeleteGroup = DeleteGroup + Group

   // Alle uebertragenen Texte, Symbole und Planes in den Layern "_make_up" und "_invis" aufsammeln
   Group = VARLayerMakeUp.list_all where valid(.user_ViewId) and
                                         .user_ViewId = view_id and
                                         not .deleted
   Group = ( VARLayerInvis.list_all where valid(.user_ViewId) and
                                          .user_ViewId = view_id and
                                          not .deleted ) + Group
   Group1 = Group where .type.name = "plane"
   DeleteGroup = DeleteGroup + Group1
   Group1 = Group where .type.name = "text"
   DeleteGroup = DeleteGroup + Group1
   Group1 = Group where .type.name = "symbol"
   DeleteGroup = DeleteGroup + Group1

   // Loeschen aller Objekte in View
   for i in DeleteGroup do
      DeleteObject(i)
   end

   // Setzen des Namens der aktuellen View
   view_name = wname + "_" + VARLayoutName

   // World mit Namen suchen.
   Group = top.list_world where .name = view_name
   if empty(Group) then 
      `Element World mit Namen "`[view_name]`" nicht gefunden` nl
      `Element kann nicht geloescht werden` nl
   else
      if len(Group) > 1 then
         Group1 = Group where not .deleted
         if not empty(Group1) then
            VARViewWorld = Group1.first 
         else
            VARViewWorld = Group.first 
         end
      else
         VARViewWorld = Group.first 
         if VARViewWorld.deleted then
            undo_delete(VARViewWorld)
         end
      end

      VARViewOrig = VARViewWorld.sons.first

      name( VARViewWorld, "" )
      layer_move_objects ({VARViewWorld, VARViewOrig}, VARLayerError)
      delete(VARViewWorld)
      delete(VARViewOrig)
      pos = VARViewWorld.par_pos.par_p
      ang = VARViewWorld.par_an
      sca = VARViewWorld.par_s
      delete(pos)
      delete(ang)
      delete(sca)
   end

   // Pruefen ob Layout World geloescht werden muss
   CheckDeleteLayoutWorld ()

end

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

function CreatePoint ( view_id, dx, dy, addgrp )
   /*   Erzeugen eines Punktes                               */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      dx      : x-Wert realativ zur lokalen World       */
   /*      dy      : y-Wert realativ zur lokalen World       */
   /*      addgrp  : Punkt in tmp. Punktgruppe aufnehmen     */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Point                                             */
   
   elem = invalid
   if addgrp then
      elem = search_point (GROUPPoint, VARViewWorld.x + dx, VARViewWorld.y + dy, 0.00001, false)
   end
   if not valid (elem) then
      elem = point_relative ( VARViewOrig, dx, dy )
      elem = elem.result
      if not VAR_EUKLID then
         delete(elem)
      end
      if addgrp then
         GROUPPoint = elem + GROUPPoint
         CreateUserAttrib (elem, "ViewId", view_id) 
      end
   end
   return (elem)

end

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

function EditPoint ( elem, dx, dy, addgrp )
   /*   Editieren eines Punktes                              */
   /*   Eingabe:                                             */
   /*      elem    : Punkt                                   */
   /*      dx      : x-Wert realativ zur lokalen World       */
   /*      dy      : y-Wert realativ zur lokalen World       */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Point                                             */

   if abs(elem.par_dx.norm - dx) > VAR_epsilon or
      abs(elem.par_dy.norm - dy) > VAR_epsilon then
      elem1 = CreatePoint ( elem.user_ViewId, dx, dy, addgrp )
   else
      elem1 = elem
   end 
   return (elem1)

end

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

function DeletePoint ( elem )
   /*   Loeschen eines Punktes                               */
   /*   Eingabe:                                             */
   /*      elem    : Punkt                                   */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   Group = elem.allsons
   if not empty(Group) then
      Group1 = Group where not valid(.user_ViewId)
      if len(Group1) = len(Group) then
         if elem.deleted then // undo delete weil layer_move_objects keine geloeschten Objekte verschiebt
            undo_delete(elem)
         end
         layer_move_objects ({elem}, VARLayerError)
         layer_move_objects (Group1, VARLayerError)
         delete_attrib(elem, "ViewId")
         delete(elem)
      end
   end

end

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

function CreateLine ( view_id, edge_id, elem_id, visib, style, limited, sp, ep )
   /*   Erzeugen oder Aenden einer Linie                     */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      edge_id : Attributwert fuer Attr. "EdgeId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      visib   : Sichtbarkeitsstatus der Linie           */
   /*      style   : Strichart der Linie                     */
   /*      limited : endliche, unendliche oder Mittel- Linie */
   /*      sp      : Startpunkt der Line {x,y}               */
   /*      ep      : Endpunkt der Linie {x,y}                */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Line                                              */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPLine)
   // Suche Objekt mit Attribut in Ansicht vom anderen Typ
   if elem = 0 then
      Group = GROUPCircle + GROUPEllips + GROUPSpline
      elem = FindObject ("ElemId", elem_id, Group)
   end
   if elem != 0 and elem.type.name != "line" then
      DeleteObject(elem)
      elem = 0
   end

   if visib != "hidden" or (visib = "hidden" and VAR_hidden)
      or (visib = "hidden" and VARViewRep = "hidden_dotted")
      or (elem != 0) then

      if elem = 0 then
         p1 = CreatePoint( view_id, sp.el_1, sp.el_2, true )
         p2 = CreatePoint( view_id, ep.el_1, ep.el_2, true )
         elem = line_pointpoint ( , style, limited, p1, p2 )
         CreateIdAttr ( elem, view_id, elem_id )
         CreateUserAttrib (elem, "EdgeId", edge_id)
      else
         p1 = elem.created_by.par_p1
         p2 = elem.created_by.par_p2
         p1 = EditPoint( p1, sp.el_1, sp.el_2, true )
         p2 = EditPoint( p2, ep.el_1, ep.el_2, true )
         edit(elem, , style, limited, p1, p2)
      end
      MoveToLayer ( elem, visib )

   end // hidden

   return (elem)

end

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

function DeleteLine ( elem_id )
   /*   Loeschen einer Linie                                 */
   /*   Eingabe:                                             */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPLine)
   if elem = 0 then
      // Suche Objekt mit Attribut in Ansicht vom anderen Typ
      Group = GROUPCircle + GROUPEllips + GROUPSpline
      elem = FindObject ("ElemId", elem_id, Group)
      if elem != 0 then
         switch elem.type.name
            case "circle":
                 DeleteCircle ( elem_id )
            case "ellips":
                 DeleteEllips ( elem_id )
            case "spline":
                 DeleteSpline ( elem_id )
         end
      end
   else
      DeleteObject(elem)
      p1 = elem.created_by.par_p1
      p2 = elem.created_by.par_p2
   end

end

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

function CreateCircle ( view_id, edge_id, elem_id, visib, style, axis, center, radius )
   /*   Erzeugen oder Aendern eines Kreises                  */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      edge_id : Attributwert fuer Attr. "EdgeId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      visib   : Sichtbarkeitsstatus des Kreises         */
   /*      style   : Strichart des Kreises                   */
   /*      axis    : Kreis mit oder ohne Achsen              */
   /*      center  : Mittelpunkt des Kreises {x, y}          */
   /*      radius  : Radius des Kreises                      */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Circle                                            */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPCircle)
   // Suche Objekt mit Attribut in Ansicht vom anderen Typ
   if elem = 0 then
      Group = GROUPLine + GROUPEllips + GROUPSpline
      elem = FindObject ("ElemId", elem_id, Group)
   end
   if elem != 0 and ( elem.created_by.type.name != "circle_centerradius" or
                      elem.type.name != "circle" ) then
      DeleteObject(elem)
      elem = 0
   end

   if visib != "hidden" or (visib = "hidden" and VAR_hidden)
      or (visib = "hidden" and VARViewRep = "hidden_dotted")
      or (elem != 0) then

      if elem = 0 then
         c = CreatePoint( view_id, center.el_1, center.el_2, true )
         elem = circle_centerradius ( , style, axis, c, radius )
         CreateIdAttr ( elem, view_id, elem_id )
         CreateUserAttrib (elem, "EdgeId", edge_id)
      else
         c = elem.created_by.par_p
         c = EditPoint( c, center.el_1, center.el_2, true )
         edit(elem, , style, axis, c, radius )
      end
      MoveToLayer ( elem, visib )

   end // hidden

   return (elem)

end

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

function CreateCircleArc ( view_id, edge_id, elem_id, visib, style, axis, center, sp, ep )
   /*   Erzeugen oder Aendern eines Kreisbogens              */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      edge_id : Attributwert fuer Attr. "EdgeId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      visib   : Sichtbarkeitsstatus des Kreisbogens     */
   /*      style   : Strichart des Kreisbogens               */
   /*      axis    : Kreisbogen mit oder ohne Achsen         */
   /*      center  : Mittelpunkt des Kreisbogens {x, y}      */
   /*      sp      : Startpunkt des Kreisbogens {x, y}       */
   /*      ep      : Endpunkt des Kreisbogens {x, y}         */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Circle                                            */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPCircle)
   // Suche Objekt mit Attribut in Ansicht vom anderen Typ
   if elem = 0 then
      Group = GROUPLine + GROUPEllips + GROUPSpline
      elem = FindObject ("ElemId", elem_id, Group)
   end
   if elem != 0 and ( elem.created_by.type.name != "circle_arc2pointsbegin" or
                      elem.type.name != "circle" ) then
      DeleteObject(elem)
      elem = 0
   end

   if visib != "hidden" or (visib = "hidden" and VAR_hidden)
      or (visib = "hidden" and VARViewRep = "hidden_dotted")
      or (elem != 0) then

      if elem = 0 then
         pc = CreatePoint( view_id, center.el_1, center.el_2, true )
         p1 = CreatePoint( view_id, sp.el_1, sp.el_2, true )
         p2 = CreatePoint( view_id, ep.el_1, ep.el_2, true )
         elem = circle_arc2pointsbegin ( , style, axis, , pc, p1, p2 )
         CreateIdAttr ( elem, view_id, elem_id )
         CreateUserAttrib (elem, "EdgeId", edge_id)
      else
         pc = elem.created_by.par_mp
         p1 = elem.created_by.par_bp
         p2 = elem.created_by.par_ep
         pc = EditPoint( pc, center.el_1, center.el_2, true )
         p1 = EditPoint( p1, sp.el_1, sp.el_2, true )
         p2 = EditPoint( p2, ep.el_1, ep.el_2, true )
         edit(elem, , style, axis, , pc, p1, p2 )
      end
      MoveToLayer ( elem, visib )

   // p3 auf Endpunkt von Arc editieren
//   EditPoint( p2, elem.x3 - VARViewOrig.x, elem.y3 - VARViewOrig.y, true )

   end // hidden

   return (elem)

end

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

function DeleteCircle ( elem_id )
   /*   Loeschen eines Kreises                               */
   /*   Eingabe:                                             */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPCircle)
   if elem = 0 then
      // Suche Objekt mit Attribut in Ansicht vom anderen Typ
      Group = GROUPLine + GROUPEllips + GROUPSpline
      elem = FindObject ("ElemId", elem_id, Group)
      if elem != 0 then
         switch elem.type.name
            case "line":
                 DeleteLine ( elem_id )
            case "ellips":
                 DeleteEllips ( elem_id )
            case "spline":
                 DeleteSpline ( elem_id )
         end
      end
   else
      DeleteObject(elem)
      if elem.created_by.type.name = "circle_centerradius" then
         c = elem.created_by.par_p
      else
         pc = elem.created_by.par_mp
         p1 = elem.created_by.par_bp
         p2 = elem.created_by.par_ep
      end
   end

end

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

function CreateEllips ( view_id, edge_id, elem_id, visib, style, axis, center, angle, maj_rad, min_rad )
   /*   Erzeugen oder Aendern einer Ellipse                  */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      edge_id : Attributwert fuer Attr. "EdgeId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      visib   : Sichtbarkeitsstatus der Ellipse         */
   /*      style   : Strichart der Ellipse                   */
   /*      axis    : Ellipse mit oder ohne Achsen            */
   /*      center  : Mittelpunkt der Ellipse {x, y}          */
   /*      angle   : Hauptachsenwinkel der Ellipse           */
   /*      maj_rad : Hauptachsenradius der Ellipse           */
   /*      min_rad : Nebenachsenradius der Ellipse           */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Ellips                                            */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPEllips)
   // Suche Objekt mit Attribut in Ansicht vom anderen Typ
   if elem = 0 then
      Group = GROUPLine + GROUPCircle + GROUPSpline
      elem = FindObject ("ElemId", elem_id, Group)
   end
   if elem != 0 and ( elem.created_by.type.name != "ellips_angle2lengths" or
                      elem.type.name != "ellips" ) then
      DeleteObject(elem)
      DeleteRefObject(elem)
      elem = 0
   end

   if visib != "hidden" or (visib = "hidden" and VAR_hidden)
      or (visib = "hidden" and VARViewRep = "hidden_dotted")
      or (elem != 0) then

      if elem = 0 then
         c = CreatePoint( view_id, center.el_1, center.el_2, true )
         elem = ellips_angle2lengths ( , style, axis, c, angle, maj_rad, min_rad )
         CreateIdAttr ( elem, view_id, elem_id )
         CreateUserAttrib (elem, "EdgeId", edge_id)
      else
         c = elem.created_by.par_mp
         c = EditPoint( c, center.el_1, center.el_2, true )
         edit(elem, , style, axis, c, angle, maj_rad, min_rad )
      end
      MoveToLayer ( elem, visib )

   end // hidden

   return (elem)

end

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

function CreateEllipsArc ( view_id, edge_id, elem_id, visib, style, axis, center, angle, maj_rad, min_rad, sp, ep )
   /*   Erzeugen oder Aendern eines Ellipsenbogens           */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      edge_id : Attributwert fuer Attr. "EdgeId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      visib   : Sichtbarkeitsstatus des Ellipsenbogens  */
   /*      style   : Strichart des Ellipsenbogens            */
   /*      axis    : Ellipsenbogen mit oder ohne Achsen      */
   /*      center  : Mittelpunkt des Ellipsenbogens {x, y}   */
   /*      angle   : Hauptachsenwinkel des Ellipsenbogens    */
   /*      maj_rad : Hauptachsenradius des Ellipsenbogens    */
   /*      min_rad : Nebenachsenradius des Ellipsenbogens    */
   /*      sp      : Startpunkt des Ellipsenbogens {x, y}    */
   /*      ep      : Endpunkt des Ellipsenbogens {x, y}      */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Ellips                                            */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPEllips)
   // Suche Objekt mit Attribut in Ansicht vom anderen Typ
   if elem = 0 then
      Group = GROUPLine + GROUPCircle + GROUPSpline
      elem = FindObject ("ElemId", elem_id, Group)
   end
   if elem != 0 and ( elem.created_by.type.name != "ellips_arc2points" or
                      elem.type.name != "ellips" ) then
      DeleteObject(elem)
      DeleteRefObject(elem)
      elem = 0
   end

   if visib != "hidden" or (visib = "hidden" and VAR_hidden)
      or (visib = "hidden" and VARViewRep = "hidden_dotted")
      or (elem != 0) then

      if elem = 0 then
         pc = CreatePoint( view_id, center.el_1, center.el_2, true )
         p1 = CreatePoint( view_id, sp.el_1, sp.el_2, true )
         p2 = CreatePoint( view_id, ep.el_1, ep.el_2, true )
         elem1 = ellips_angle2lengths ( , style, axis, pc, angle, maj_rad, min_rad )
         elem = ellips_arc2points ( , style, axis, elem1, p1, p2 )
         CreateIdAttr ( elem, view_id, elem_id )
         CreateUserAttrib (elem, "EdgeId", edge_id)
      else
         elem1 = elem.created_by.par_e
         pc = elem1.created_by.par_mp
         p1 = elem.created_by.par_p_1
         p2 = elem.created_by.par_p_2
         pc = EditPoint( pc, center.el_1, center.el_2, true )
         p1 = EditPoint( p1, sp.el_1, sp.el_2, true )
         p2 = EditPoint( p2, ep.el_1, ep.el_2, true )
         edit(elem1, , style, axis, pc, angle, maj_rad, min_rad )
         edit(elem, , style, axis, elem1, p1, p2 )
      end
      MoveToLayer ( elem, visib )

   // p3 auf Endpunkt von Arc editieren
//   EditPoint( p2, elem.x3 - VARViewOrig.x, elem.y3 - VARViewOrig.y, true )

   end // hidden

   return (elem)

end

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

function DeleteEllips ( elem_id )
   /*   Loeschen einer Ellipse                               */
   /*   Eingabe:                                             */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPEllips)
   if elem = 0 then
      // Suche Objekt mit Attribut in Ansicht vom anderen Typ
      Group = GROUPCircle + GROUPLine + GROUPSpline
      elem = FindObject ("ElemId", elem_id, Group)
      if elem != 0 then
         switch elem.type.name
            case "circle":
                 DeleteCircle ( elem_id )
            case "line":
                 DeleteLine ( elem_id )
            case "spline":
                 DeleteSpline ( elem_id )
         end
      end
   else
      DeleteObject(elem)
      if elem.created_by.type.name = "ellips_angle2lengths" then
         c = elem.created_by.par_mp
      else
         elem1 = elem.created_by.par_e
         delete(elem1)
         pc = elem1.created_by.par_mp
         p1 = elem.created_by.par_p_1
         p2 = elem.created_by.par_p_2
      end
   end

end

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

function CreateSpline ( view_id, edge_id, elem_id, visib, style, deg, var points, var knots )
   /*   Erzeugen oder Aendern eines Spline                   */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      edge_id : Attributwert fuer Attr. "EdgeId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      visib   : Sichtbarkeitsstatus des Spline          */
   /*      style   : Strichart des Spline                    */
   /*      deg     : Grad des Spline                         */
   /*      points  : Gruppe von Stuetzpunkten                */
   /*      knots   : Gruppe von Knotenvektoren               */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Spline                                            */

   if empty(points) then
      `Keine Stuetzpunkte fuer Spline vorhanden` nl
   end
   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPSpline)
   // Suche Objekt mit Attribut in Ansicht vom anderen Typ
   if elem = 0 then
      Group = GROUPLine + GROUPCircle + GROUPEllips
      elem = FindObject ("ElemId", elem_id, Group)
   end
   if elem != 0 and ( elem.created_by.type.name != "spline_controlpol" or
                      elem.type.name != "spline" ) then
      DeleteObject(elem)
      DeleteRefObject(elem)
      elem = 0
   end

   if visib != "hidden" or (visib = "hidden" and VAR_hidden)
      or (visib = "hidden" and VARViewRep = "hidden_dotted")
      or (elem != 0) then

      if len(points) <= deg then
         deg = len(points) - 1
      end
      if elem = 0 then
         Group = {}
         for i in points
            p = CreatePoint( view_id, i.el_1, i.el_2, false )
            Group = Group + {{ p, i.el_3 }}
         end
         elem = spline_controlpol ( , style, "chordal", false, deg, Group, knots)
         CreateIdAttr ( elem, view_id, elem_id )
         CreateUserAttrib (elem, "EdgeId", edge_id)
      else
         Group1 = {}
         Group_np = {}
         Group = elem.created_by.par_list
         ind = 1
         for i in points
            if ind <= len(Group) then
               GroupTmp = index(Group, ind)
               p = EditPoint( GroupTmp.el_1, i.el_1, i.el_2, false )
            else
               p = CreatePoint( view_id, i.el_1, i.el_2, false )
            end
            Group1 = Group1 + {{ p, i.el_3 }}
            Group_np = Group_np + {p,index(Group, ind)}
            ind = ind + 1
         end
         edit(elem, , style, "chordal", false, deg, Group1, knots)
      end
      MoveToLayer ( elem, visib )

   end // hidden

   return (elem)

end

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

function CreateSplinePart ( view_id, edge_id, elem_id, visib, style, deg, var points, var knots, sp, ep )
   /*   Erzeugen oder Aendern eines Spline                   */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      edge_id : Attributwert fuer Attr. "EdgeId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      visib   : Sichtbarkeitsstatus des Spline          */
   /*      style   : Strichart des Spline                    */
   /*      deg     : Grad des Spline                         */
   /*      points  : Gruppe von Stuetzpunkten                */
   /*      knots   : Gruppe von Knotenvektoren               */
   /*      sp      : Startparameter                          */
   /*      ep      : Endeparameter                           */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Spline                                            */

   if empty(points) then
      `Keine Stuetzpunkte fuer Spline vorhanden` nl
   end
   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPSpline)
   // Suche Objekt mit Attribut in Ansicht vom anderen Typ
   if elem = 0 then
      Group = GROUPLine + GROUPCircle + GROUPEllips
      elem = FindObject ("ElemId", elem_id, Group)
   end
   if elem != 0 and ( elem.created_by.type.name != "spline_cutonpoints" or
                      elem.type.name != "spline" ) then
      DeleteObject(elem)
      DeleteRefObject(elem)
      elem = 0
   end

   if visib != "hidden" or (visib = "hidden" and VAR_hidden)
      or (visib = "hidden" and VARViewRep = "hidden_dotted")
      or (elem != 0) then

      if len(points) <= deg then
         deg = len(points) - 1
      end
      if elem = 0 then
         elem1 = 0
         // Pruefen ob Referenzobjekt mit Attribut gesetzt
         if valid(VAR_RefSpline) and valid(VAR_RefSpline.created_by.type.name) and
            VAR_RefSpline.created_by.type.name = "spline_controlpol" and
            valid(VAR_RefSpline.user_EdgeId) and VAR_RefSpline.user_EdgeId = edge_id then
            elem1 = VAR_RefSpline
         end
         if elem1 = 0 then
            Group = {}
            for i in points
               p = CreatePoint( view_id, i.el_1, i.el_2, false )
               Group = Group + {{ p, i.el_3 }}
            end
            elem1 = spline_controlpol ( , style, "chordal", false, deg, Group, knots)
            CreateUserAttrib (elem1, "EdgeId", edge_id)
            VAR_RefSpline = elem1.result
         end
         elem = spline_cutonpoints ( , style, elem1, sp, ep, {0,0} )
         CreateIdAttr ( elem, view_id, elem_id )
         CreateUserAttrib (elem, "EdgeId", edge_id)
      else
         Group1 = {}
         Group_np = {}
         elem1 = elem.created_by.par_sp
         Group = elem1.created_by.par_list
         if not valid(VAR_RefSpline) or (valid(VAR_RefSpline) and elem1 != VAR_RefSpline) then
            ind = 1
            for i in points
               if ind <= len(Group) then
                  GroupTmp = index(Group, ind)
                  p = EditPoint( GroupTmp.el_1, i.el_1, i.el_2, false )
               else
                  p = CreatePoint( view_id, i.el_1, i.el_2, false )
               end
               Group1 = Group1 + {{ p, i.el_3 }}
               Group_np = Group_np + {p,index(Group, ind)}
               ind = ind + 1
            end
            VAR_RefSpline = elem1
         else
            Group1 = Group
         end
         edit(elem1, , style, "chordal", false, deg, Group1, knots)
         edit(elem, , style, elem1, sp, ep, )
      end
      MoveToLayer ( elem, visib )

   end // hidden

   return (elem)

end

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

function DeleteSpline ( elem_id )
   /*   Loeschen eines Spline                                */
   /*   Eingabe:                                             */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPSpline)
   if elem = 0 then
      // Suche Objekt mit Attribut in Ansicht vom anderen Typ
      Group = GROUPCircle + GROUPEllips + GROUPLine
      elem = FindObject ("ElemId", elem_id, Group)
      if elem != 0 then
         switch elem.type.name
            case "circle":
                 DeleteCircle ( elem_id )
            case "ellips":
                 DeleteEllips ( elem_id )
            case "line":
                 DeleteLine ( elem_id )
         end
      end
   else
      if elem.created_by.type.name = "spline_cutonpoints" then
         delete_attrib(elem.created_by.par_sp, "EdgeId")
      end
      DeleteObject(elem)
      // Suche evtl. 2. Teilstueck
      elem = FindObject ("ElemId", elem_id+"_1", GROUPSpline)
      if elem != 0 then
         DeleteObject(elem)
      end
   end

end

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

function CreateContour        ( view_id, elem_id, elem_group )
   /*   Erzeugen einer Kontur                                */
   /*   Eingabe:                                             */
   /*      view_id    : Attributwert fuer Attr. "ViewId"     */
   /*      elem_id    : Attributwert fuer Attr. "ElemId"     */
   /*      elem_group : Gruppe mit Konturelementen           */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Kontur                                            */

   ContElem = {}
   elem = 0
   for elem in elem_group do
      switch elem.el_1
         case "Line" :
            // { "Line", "visible", { "solid", 3 }, "is_limited", {50, 0}, {-20, 0} }
            p1 = CreatePoint( view_id, elem.el_5.el_1, elem.el_5.el_2, true )
            p2 = CreatePoint( view_id, elem.el_6.el_1, elem.el_6.el_2, true )
            geo_elem = line_pointpoint ( , elem.el_3, elem.el_4, p1, p2 )
         case "Circle" :
            // { "Circle", "visible", { "solid", 3 }, "no_axes", {50, 0}, 20 }
            c = CreatePoint( view_id, elem.el_5.el_1, elem.el_5.el_2, true )
            geo_elem = circle_centerradius ( , elem.el_3, elem.el_4, c, elem.el_6 )
         case "CircleArc" :
            // { "CircleArc", "visible", { "solid", 3 }, "no_axes", {-36, 13}, {-20, 0}, {-50, 29} }
            pc = CreatePoint( view_id, elem.el_5.el_1, elem.el_5.el_2, true )
            p1 = CreatePoint( view_id, elem.el_6.el_1, elem.el_6.el_2, true )
            p2 = CreatePoint( view_id, elem.el_7.el_1, elem.el_7.el_2, true )
            geo_elem = circle_arc2pointsbegin ( , elem.el_3, elem.el_4, , pc, p1, p2 )
         case "Ellips" :
            // { "Ellips", "visible", { "solid", 3 }, "no_axes", {50, 0}, 45, 20, 10 }
            c = CreatePoint( view_id, elem.el_5.el_1, elem.el_5.el_2, true )
            geo_elem = ellips_angle2lengths ( , elem.el_3, elem.el_4, c, elem.el_6, elem.el_7, elem.el_8 )
         case "EllipsArc" :
            // { "Ellips", "visible", { "solid", 3 }, "no_axes", {50, 0}, 45, 20, 10, {20, -5}, {50, 10} }
            pc = CreatePoint( view_id, elem.el_5.el_1, elem.el_5.el_2, true )
            p1 = CreatePoint( view_id, elem.el_9.el_1, elem.el_9.el_2, true )
            p2 = CreatePoint( view_id, elem.el_10.el_1, elem.el_10.el_2, true )
            geo_elem1 = ellips_angle2lengths ( , elem.el_3, elem.el_4, pc, elem.el_6, elem.el_7, elem.el_8 )
            geo_elem = ellips_arc2points ( , elem.el_3, elem.el_4, geo_elem1, p1, p2 )
         case "Spline" :
            // { "SplinePart", "visible", { "solid", 3 }, 3, {<points>}, {<knots>} }
            Group = {}
            for i in elem.el_5
               p = CreatePoint( view_id, i.el_1, i.el_2, false )
               Group = Group + {{ p, i.el_3 }}
            end
            geo_elem = spline_controlpol ( , elem.el_3, "chordal", false, elem.el_4, Group, elem.el_6)
         case "SplinePart" :
            // { "SplinePart", "visible", { "solid", 3 }, 3, 0, 0, {<points>}, {<knots>} }
            Group = {}
            for i in elem.el_7
               p = CreatePoint( view_id, i.el_1, i.el_2, false )
               Group = Group + {{ p, i.el_3 }}
            end
            geo_elem1 = spline_controlpol ( , elem.el_3, "chordal", false, elem.el_4, Group, elem.el_8)
            geo_elem = spline_cutonpoints ( , elem.el_3, geo_elem1, elem.el_5, elem.el_6, {0,0} )
      end
      if elem.el_1 != "Spline" and elem.el_1 != "SplinePart" then
         ContElem = ContElem + geo_elem
         if not VAR_EUKLID then
            delete(geo_elem)
         end
      end
   end

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPContour)
   if elem = 0 then
      elem = contour_ofelements ( , ContElem )
      CreateIdAttr ( elem, view_id, elem_id )
   else
      edit( elem, , ContElem )
   end

   return (elem)

end

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

function DeleteContour ( elem_id )
   /*   Loeschen einer kontour                               */
   /*   Eingabe:                                             */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */
   /*                                                        */
   /*  Beschreibung:                                         */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPContour)
   if elem = 0 then
      `Element Kontur mit ID "`[elem_id]`" nicht gefunden` nl
      `Element kann nicht geloescht werden` nl
   else
      DeleteObject(elem)
   end

   return (elem)

end

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

function CreatePosttext ( post )
   /*   Erzeugen eines Posttextes                            */
   /*   Eingabe:                                             */
   /*      post    : Gruppe oder String fuer Posttext        */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Posttext                                          */

   // Erzeuge Objekt Posttext
   if type(post) = "group" then
      post_elem = posttext_minandmax (post.el_1, post.el_2)
   else if type(post) = "string" and len(post) > 0 then
      post_elem = posttext_fit (post)
   else
      post_elem = posttext_pnul ()
   end
   end

   return (post_elem)

end

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

function EditPosttext ( elem, post )
   /*   Editieren eines Posttextes                           */
   /*   Eingabe:                                             */
   /*      elem    : Posttext Objekt                         */
   /*      post    : Gruppe oder String fuer Posttext        */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Posttext                                          */

   // Editiere Objekt Posttext
   if type(post) = "group" then
      if elem.created_by.type.name = "posttext_minandmax" then
         edit(elem.par_down, post.el_1)
         edit(elem.par_up, post.el_2)
      else
         delete(elem)
         elem = CreatePosttext(post)
      end
   else if type(post) = "string" and len(post) > 0 then
      if elem.created_by.type.name = "posttext_fit" then
         edit(elem.par_s, post)
      else
         delete(elem)
         elem = CreatePosttext(post)
      end
   else if type(post) = "string" and len(post) = 0 then
      if elem.created_by.type.name != "posttext_pnul" then
         delete(elem)
         elem = posttext_pnul ()
      end
   end
   end
   end

   return (elem)

end

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

function SetMeasureInfo ( part_id, feature_id, par_name, par_formula )
   /*   Setzt Informationsdaten fuer Masse vom Type 4        */
   /*   Eingabe:                                             */
   /*      part_id     : Attributwert fuer Attr. "PartId"    */
   /*      feature_id  : Attributwert fuer Attr. "FeatureId" */
   /*      par_name    : Attributwert fuer Attr. "ParName"   */
   /*      par_formula : Attributwert fuer Attr. "ParFormula"*/
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   VARPartId      = part_id
   VARFeatureId   = feature_id
   VARParName     = par_name
   VARParFormula  = par_formula

end

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

function CreateMeasureP1P2 ( view_id, elem_id, mtype, control, pre, post, comment, proj, p1, p2, pos )
   /*   Erzeugen oder Aendern eines Abstandmasses            */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      mtype   : Masstype                                */
   /*      control : Darstellung des Masses (Gruppe)         */
   /*      pre     : Vortext                                 */
   /*      post    : Nochtext                                */
   /*      comment : Kommentar                               */
   /*      proj    : Winkel                                  */
   /*      p1      : Masspunkt 1 {x, y}                      */
   /*      p2      : Masspunkt 2 {x, y}                      */
   /*      pos     : Massposition bezogen auf p1 Laenge      */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Measure                                           */

   if pre = "-" then
      pre = ""
   end
   if comment = "-" then
      comment = ""
   end

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPDimention)
   if elem = 0 then
      post_elem = CreatePosttext(post)

      mp1 = CreatePoint( view_id, p1.el_1, p1.el_2, true )
      mp2 = CreatePoint( view_id, p2.el_1, p2.el_2, true )
      elem = measure_plc1plc2 ( control, pre, post_elem, comment, "Helvetica", 0.0, 1.0, 3.5, proj, { 0, 0, 0 }, mp1, mp2, pos, 0)
      CreateIdAttr ( elem, view_id, elem_id )

      if mtype = 4 then
         CreateMeasInfoAttr ( elem )
      end

      // Mass in Layer schieben
      if mtype = 4 then
         layer_move_objects ({elem}, VARLayerKey)
      else
         layer_move_objects ({elem}, VARLayerMakeUp)
      end
   else
      mpost = elem.par_post
      mpre = elem.par_pre
      mcomm = elem.par_comment
      mpost = EditPosttext(mpost, post)
      edit(mpre, pre)
      edit(mcomm, comment)

      mp1 = elem.created_by.par_plc1
      mp2 = elem.created_by.par_plc2
      mpos = elem.created_by.par_pos
      mp1 = EditPoint( mp1, p1.el_1, p1.el_2, true )
      mp2 = EditPoint( mp2, p2.el_1, p2.el_2, true )
      if VARUpdMeasPos then
         edit(mpos, pos)
      end
      edit(elem, control, , mpost, , , , , , proj, , mp1, mp2, , 0)
   end

   return (elem)

end

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

function CreateMeasureAngle ( view_id, elem_id, mtype, control, pre, post, comment, p1, p2, p3, pos )
   /*   Erzeugen oder Aendern eines Winkelmasses             */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      mtype   : Masstype                                */
   /*      control : Darstellung des Masses (Gruppe)         */
   /*      pre     : Vortext                                 */
   /*      post    : Nochtext                                */
   /*      comment : Kommentar                               */
   /*      p1      : Masspunkt 1 {x, y}                      */
   /*      p2      : Masspunkt 2 {x, y}                      */
   /*      p3      : Masspunkt 2 {x, y}                      */
   /*      pos     : Massposition bezogen auf p1 Laenge      */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Measure                                           */

   if pre = "-" then
      pre = ""
   end
   if comment = "-" then
      comment = ""
   end

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPDimention)
   if elem = 0 then
      post_elem = CreatePosttext(post)

      mp1 = CreatePoint( view_id, p1.el_1, p1.el_2, true )
      mp2 = CreatePoint( view_id, p2.el_1, p2.el_2, true )
      mp3 = CreatePoint( view_id, p3.el_1, p3.el_2, true )
 //     elem = measure_angle2lines ( control, pre, post_elem, comment, "Helvetica", 0.0, 1.0, 3.5, { 0, 0, 0 }, "is_shortmeasure", l1, l2, { posx, posy, 0 }, { true, true })
      elem = measure_angle3points ( control, pre, post_elem, comment, "Helvetica", 0.0, 1.0, 3.5, { 0, 0, 0 }, "is_shortmeasure", mp3, mp2, mp1, pos)
      CreateIdAttr ( elem, view_id, elem_id )

      if mtype = 4 then
         CreateMeasInfoAttr ( elem )
      end

      // Mass in Layer schieben
      if mtype = 4 then
         layer_move_objects ({elem}, VARLayerKey)
      else
         layer_move_objects ({elem}, VARLayerMakeUp)
      end
   else
      mpost = elem.par_post
      mpre = elem.par_pre
      mcomm = elem.par_comment
      EditPosttext(mpost, post)
      edit(mpre, pre)
      edit(mcomm, comment)

      mp3 = elem.created_by.par_p1
      mp2 = elem.created_by.par_p2
      mp1 = elem.created_by.par_p3
      mpos = elem.created_by.par_pos
      if VARUpdMeasPos then
         edit(mpos, pos)
      end
      mp1 = EditPoint( mp1, p1.el_1, p1.el_2, true )
      mp2 = EditPoint( mp2, p2.el_1, p2.el_2, true )
      mp3 = EditPoint( mp3, p3.el_1, p3.el_2, true )
      edit(elem, control, , , , , , , , , , mp3, mp2, mp1, )
   end

   return (elem)

end

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

function CreateMeasureDiam ( view_id, elem_id, mtype, control, pre, post, comment, proj, p1, p2, pos )
   /*   Erzeugen oder Aenden eines Durchmessermasses         */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      mtype   : Masstype                                */
   /*      control : Darstellung des Masses (Gruppe)         */
   /*      pre     : Vortext                                 */
   /*      post    : Nochtext                                */
   /*      comment : Kommentar                               */
   /*      proj    : Winkel                                  */
   /*      p1      : Masspunkt 1 {x, y}                      */
   /*      p2      : Masspunkt 2 {x, y}                      */
   /*      pos     : Massposition bezogen auf p1 Laenge      */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Measure                                           */

   if pre = "-" then
      pre = ""
   end
   if comment = "-" then
      comment = ""
   end

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPDimention)
   if elem = 0 then
      post_elem = CreatePosttext(post)

      mp1 = CreatePoint( view_id, p1.el_1, p1.el_2, true )
      mp2 = CreatePoint( view_id, p2.el_1, p2.el_2, true )
      elem = measure_plc1plc2 ( control, pre, post_elem, comment, "Helvetica", 0.0, 1.0, 3.5, proj, { 0, 0, 0 }, mp1, mp2, pos, 0)
      CreateIdAttr ( elem, view_id, elem_id )

      if mtype = 4 then
         CreateMeasInfoAttr ( elem )
      end

      // Mass in Layer schieben
      if mtype = 4 then
         layer_move_objects ({elem}, VARLayerKey)
      else
         layer_move_objects ({elem}, VARLayerMakeUp)
      end
   else
      mpost = elem.par_post
      mpre = elem.par_pre
      mcomm = elem.par_comment
      EditPosttext(mpost, post)
      edit(mpre, pre)
      edit(mcomm, comment)

      mp1 = elem.created_by.par_plc1
      mp2 = elem.created_by.par_plc2
      mpos = elem.created_by.par_pos
      if VARUpdMeasPos then
         edit(mpos, pos)
      end
      mp1 = EditPoint( mp1, p1.el_1, p1.el_2, true )
      mp2 = EditPoint( mp2, p2.el_1, p2.el_2, true )
      edit(elem, control, , , , , , , , proj, , mp1, mp2, , 0)
   end

   return (elem)

end

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

function CreateMeasureRad ( view_id, elem_id, mtype, control, pre, post, comment, cen, rad, pos )
   /*   Erzeugen oder Aendern eines Radienmasses             */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      mtype   : Masstype                                */
   /*      control : Darstellung des Masses (Gruppe)         */
   /*      pre     : Vortext                                 */
   /*      post    : Nochtext                                */
   /*      comment : Kommentar                               */
   /*      cen     : Mittelpunkt Dummykreis                  */
   /*      rad     : Radius Dummykreis                       */
   /*      pos     : Massposition bezogen auf p1 Laenge      */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Measure                                           */

   if pre = "-" then
      pre = ""
   end
   if comment = "-" then
      comment = ""
   end

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPDimention)
   if elem = 0 then
      post_elem = CreatePosttext(post)

      mp = CreatePoint( view_id, cen.el_1, cen.el_2, true )
      delete(mp)
      circle = circle_centerradius ( , , , mp, rad )
      delete(circle)
      elem = measure_radiusofsect ( control, pre, post_elem, comment, "Helvetica", 0.0, 1.0, 3.5, { 0, 0, 0 }, "is_shortradiusmeasure", circle, pos)
      CreateIdAttr ( elem, view_id, elem_id )

      if mtype = 4 then
         CreateMeasInfoAttr ( elem )
      end

      // Mass in Layer schieben
      if mtype = 4 then
         layer_move_objects ({elem}, VARLayerKey)
      else
         layer_move_objects ({elem}, VARLayerMakeUp)
      end
   else
      mpost = elem.par_post
      mpre = elem.par_pre
      mcomm = elem.par_comment
      EditPosttext(mpost, post)
      edit(mpre, pre)
      edit(mcomm, comment)

      circle = elem.created_by.par_c
      mp = circle.created_by.par_p
      mpos = elem.created_by.par_pos
      if VARUpdMeasPos then
         edit(mpos, pos)
      end
      mp = EditPoint( mp, cen.el_1, cen.el_2, true )
      edit(circle,  , , , mp, rad )
      edit(elem, control, , , , , , , , , , , )
   end

   return (elem)

end

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

function DeleteMeasure ( elem_id )
   /*   Loeschen eines Masses                                */
   /*   Eingabe:                                             */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPDimention)
   if elem = 0 then
      `Element Mass mit ID "`[elem_id]`" nicht gefunden` nl
      `Element kann nicht geloescht werden` nl
   else
      DeleteObject(elem)
      mpost = elem.par_post
      mpos  = elem.created_by.par_pos
      mpre  = elem.par_pre
      mcomm = elem.par_comment
      delete(mpost)
      delete(mpos)
      delete(mpre)
      delete(mcomm)

      if elem.created_by.type.name = "measure_plc1plc2" then
         mp1 = elem.created_by.par_plc1
         mp2 = elem.created_by.par_plc2
      else if elem.created_by.type.name = "measure_angle3points" then
         mp3 = elem.created_by.par_p1
         mp2 = elem.created_by.par_p2
         mp1 = elem.created_by.par_p3
      end
      end
   end

   return (elem)

end

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

function FindRefElements ( var ref_ids )
   /*   Referenzobjekte eine Plane suchen                    */
   /*   Eingabe:                                             */
   /*      ref_ids : Gruppe mit Referenz-ID's                */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Gruppe mit Referenzobjekten                       */

   ref_elem = {}
   Group_line   = top.list_line where valid(.user_EdgeId)
   Group_circle = top.list_circle where valid(.user_EdgeId)
   Group_ellips = top.list_ellips where valid(.user_EdgeId)
   for j in ref_ids
      Group = Group_line where .user_EdgeId = j
      if empty(Group) then
         Group = Group_circle where .user_EdgeId = j
         if empty(Group) then
            Group = Group_ellips where .user_EdgeId = j
            if empty(Group) then
               `Kein gueltigen Begrenzungselement mit ID "`[j]`" gefunden` nl
               `Keine Flaeche erzeugt` nl
               return ({})
            end
         end
      end
      ref_elem = ref_elem + Group
   end
   return (ref_elem)

end

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

function CreatePlane ( view_id, elem_id, dist, angle, var ref_ids )
   /*   Erzeugen oder Aendern einer Plane                    */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      dist    : Abstand Schrafffurlinien                */
   /*      angle   : Winkel Schrafffurlinien                 */
   /*      ref_ids : Gruppe mit Element-ID's                 */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Plane                                             */
   /*                                                        */
   /*  Beschreibung:                                         */

   if empty(ref_ids) then
      `Keine Element ID's fuer Plane vorhanden` nl
   end
   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPPlane)
   ref_elem = FindRefElements( ref_ids )
   if not empty(ref_elem) then
      if elem = 0 then
         elem = plane_ofelements (0.0, { 0, 0, 0 }, { "hatch_single", false }, ref_elem, dist, angle)
         CreateIdAttr ( elem, view_id, elem_id )

         // Plane in Layer schieben
         layer_move_objects ({elem}, VARLayerMakeUp)
      else
         edit(elem, , , , ref_elem, dist, angle)
      end
   end

   return (elem)

end

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

function DeletePlane ( elem_id )
   /*   Loeschen einer Plane                                 */
   /*   Eingabe:                                             */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */
   /*                                                        */
   /*  Beschreibung:                                         */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPPlane)
   if elem = 0 then
      `Element Plane mit ID "`[elem_id]`" nicht gefunden` nl
      `Element kann nicht geloescht werden` nl
   else
      DeleteObject(elem)
   end

   return (elem)

end

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

function CreateSectionDef ( view_id, elem_id, name, view_dir, coord1, coord2, sect_p )
   /*   Erzeugen oder Aendern eines Schnittliniensymbols     */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      name    : Name des Schnittlinie                   */
   /*      view_dir: Blickrichtung {x, y}                    */
   /*      sect_p  : Gruppe mit Schnittlinienpositionen      */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Symbol Section                                    */
   /*                                                        */
   /*  Beschreibung:                                         */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPSymbol)
   if elem = 0 then
      Group = {}
      for i in sect_p
         // Vorbelegung von Parameter pos und text
         if i = sect_p.first then
            coord = coord1
            text = name
         else if i = index(sect_p, len(sect_p) ) then
            coord = coord2
            text = name
         else
            coord = {0, 0, 0}
            text = ""
         end
         end

         p = CreatePoint( view_id, i.el_1, i.el_2, true )
         Group1 = {p, text, coord}
         Group = Group + {Group1}
      end
      elem = symbol_section ("Helvetica", 0.0, 1.0, 3.5, "dotted", Group)
      CreateIdAttr ( elem, view_id, elem_id )

      // Symbol in Layer schieben
      layer_move_objects ({elem}, VARLayerMakeUp)
   else
      Group1 = {}
      Group_np = {}
      Group = elem.created_by.par_star_section
      ind = 1
      for i in sect_p
         // Vorbelegung von Parameter pos und text
         if i = sect_p.first then
            coord = coord1
            text = name
         else if i = index(sect_p, len(sect_p) ) then
            coord = coord2
            text = name
         else
            coord = {0, 0, 0}
            text = ""
         end
         end

         if ind <= len(Group) then
            GroupTmp = index(Group, ind)
            p = EditPoint( GroupTmp.el_1, i.el_1, i.el_2, true )
            edit( GroupTmp.el_2, text )
            edit( GroupTmp.el_3, coord )
            Group1 = Group1 + {{p, GroupTmp.el_2, GroupTmp.el_3}}
         else
            p = CreatePoint( view_id, i.el_1, i.el_2, true )
            Group1 = Group1 + {{p, text, coord}}
         end
         ind = ind + 1
      end
      edit(elem, , , , , , Group1)
   end

   return (elem)

end

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

function DeleteSectionDef ( elem_id )
   /*   Loeschen eines Schnittliniensymbols                  */
   /*   Eingabe:                                             */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */
   /*                                                        */
   /*  Beschreibung:                                         */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPSymbol)
   if elem = 0 then
      `Element Plane mit ID "`[elem_id]`" nicht gefunden` nl
      `Element kann nicht geloescht werden` nl
   else
      DeleteObject(elem)
      Group = elem.created_by.par_star_section
      ind = 1
      while ind <= len(Group) do
         Group1 = index(Group, ind)
         delete( Group1.el_2 )
         delete( Group1.el_3 )
         ind = ind + 1
      end
   end

   return (elem)

end

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

function CreateSectionText ( view_id, elem_id, name, pos )
   /*   Erzeugen oder Aendern eines Schnittverlaufstextes    */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      name    : Name des Schnittverlaufes               */
   /*      pos     : Textposition                            */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Text                                              */
   /*                                                        */
   /*  Beschreibung:                                         */

   text = name + "-" + name
   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPText)
   if elem = 0 then
      pk = CreatePoint( view_id, pos.el_1, pos.el_2, true )
      elem = text_absolute ("Helvetica", 0.0, 1.0, "mnone", "middlev", text, pk, 3.5)
      CreateIdAttr ( elem, view_id, elem_id )

      // Text in Layer schieben
      layer_move_objects ({elem}, VARLayerMakeUp)
   else
      st = elem.created_by.par_st
      pk = elem.created_by.par_pk
      edit(st, text)
      pk = EditPoint( pk, pos.el_1, pos.el_2, true )
      edit(elem, , , , , , , pk, )
   end

   return (elem)

end

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

function DeleteSectionText ( elem_id )
   /*   Loeschen eines Schnittverlaufstextes                 */
   /*   Eingabe:                                             */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */
   /*                                                        */
   /*  Beschreibung:                                         */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPText)
   if elem = 0 then
      `Element Plane mit ID "`[elem_id]`" nicht gefunden` nl
      `Element kann nicht geloescht werden` nl
   else
      DeleteObject(elem)
      st = elem.created_by.par_st
      pk = elem.created_by.par_pk
      delete(st)
      remove_action(elem.created_by)
   end

end

//********************************************************************
// ============================================================

function CreateDetailDef ( view_id, elem_id, name, center, txpos, radius )
   /*   Erzeugen oder Aendern eines Detailausschnittes       */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      name    : Name des Detailausschnittes             */
   /*      center  : Mittelpunkt des Detailkreises {x, y}    */
   /*      txpos   : Textposition des Detailtextes {x, y}    */
   /*      radius  : Radius des Detailkreises                */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Kreis                                             */
   /*                                                        */
   /*  Beschreibung:                                         */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPCircle)
   if elem = 0 then
      c = CreatePoint( view_id, center.el_1, center.el_2, true )
      elem = circle_centerradius ( , { "solid", 3 }, "no_axes", c, radius )
      CreateIdAttr ( elem, view_id, elem_id )
   else
      c = elem.created_by.par_p
      c = EditPoint( c, center.el_1, center.el_2, true )
      edit(elem, , , , c, radius )
   end

   // Erzeuge Text fuer Detailausschnittes
   CreateDetailText ( view_id, elem_id, name, txpos )

   return (elem)

end

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

function DeleteDetailDef ( elem_id )
   /*   Loeschen eines Detailausschnittes                    */
   /*   Eingabe:                                             */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */
   /*                                                        */
   /*  Beschreibung:                                         */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPCircle)
   if elem = 0 then
      `Element Kreis mit ID "`[elem_id]`" nicht gefunden` nl
      `Element kann nicht geloescht werden` nl
   else
      DeleteObject(elem)
      c = elem.created_by.par_p
      DeleteDetailText ( elem_id )
   end

   // Loeschen Text der Detailausschnittes
   DeleteDetailText ( elem_id )

   return (elem)

end

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

function CreateDetailText ( view_id, elem_id, name, pos )
   /*   Erzeugen oder Aendern eines Detailausschnitttextes   */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      name    : Name des Detailausschnittes             */
   /*      pos     : Textposition                            */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Text                                              */
   /*                                                        */
   /*  Beschreibung:                                         */

   text = name
//   text = name + "-" + name
   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPText)
   if elem = 0 then
      pk = CreatePoint( view_id, pos.el_1, pos.el_2, true )
      elem = text_absolute ("Helvetica", 0.0, 1.0, "mnone", "middlev", text, pk, 3.5)
      CreateIdAttr ( elem, view_id, elem_id )

      // Text in Layer schieben
      layer_move_objects ({elem}, VARLayerMakeUp)
   else
      st = elem.created_by.par_st
      pk = elem.created_by.par_pk
      edit(st, text)
      pk = EditPoint( pk, pos.el_1, pos.el_2, true )
      edit(elem, , , , , , , pk, )
   end

   return (elem)

end

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

function DeleteDetailText ( elem_id )
   /*   Loeschen eines Detailausschnitttextes                */
   /*   Eingabe:                                             */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */
   /*                                                        */
   /*  Beschreibung:                                         */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPText)
   if elem = 0 then
      `Element Plane mit ID "`[elem_id]`" nicht gefunden` nl
      `Element kann nicht geloescht werden` nl
   else
      DeleteObject(elem)
      st = elem.created_by.par_st
      pk = elem.created_by.par_pk
      delete(st)
      remove_action(elem.created_by)
   end

end

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

function CreateRotLine ( view_id, elem_id, num, sp1, ep1, sp2, ep2 )
   /*   Erzeugen oder Aendern eines Detailausschnitttextes   */
   /*   Eingabe:                                             */
   /*      view_id : Attributwert fuer Attr. "ViewId"        */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*      num     : Anzahl Linien                           */
   /*      sp1     : Startpunkt 1. Rotationslinie            */
   /*      ep1     : Endpunkt   1. Rotationslinie            */
   /*      sp2     : Startpunkt 2. Rotationslinie            */
   /*      ep2     : Endpunkt   2. Rotationslinie            */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      Line(s)                                           */
   /*                                                        */
   /*  Beschreibung:                                         */

   new_elem_id = elem_id + "_1"
   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPLine)
   if elem = 0 then
      p1 = CreatePoint( view_id, sp1.el_1, sp1.el_2, true )
      p2 = CreatePoint( view_id, ep1.el_1, ep1.el_2, true )
      elem = line_pointpoint ( , {"dashdotted", 0.25}, "is_limited", p1, p2 )
      CreateIdAttr ( elem, view_id, new_elem_id )
   else
      p1 = elem.created_by.par_p1
      p2 = elem.created_by.par_p2
      p1 = EditPoint( p1, sp1.el_1, sp1.el_2, true )
      p2 = EditPoint( p2, ep1.el_1, ep1.el_2, true )
      edit(elem, , , , p1, p2)
   end

   if num = 2 then
      new_elem_id = elem_id + "_2"
      // Suche Objekt mit Attribut in Ansicht
      elem = FindObject ("ElemId", new_elem_id, GROUPLine)
      if elem = 0 then
         p1 = CreatePoint( view_id, sp2.el_1, sp2.el_2, true )
         p2 = CreatePoint( view_id, ep2.el_1, ep2.el_2, true )
         elem = line_pointpoint ( , {"dashdotted", 0.25}, "is_limited", p1, p2 )
         CreateIdAttr ( elem, view_id, new_elem_id )
      else
         p1 = elem.created_by.par_p1
         p2 = elem.created_by.par_p2
         p1 = EditPoint( p1, sp2.el_1, sp2.el_2, true )
         p2 = EditPoint( p2, ep2.el_1, ep2.el_2, true )
         edit(elem, , , , p1, p2)
      end
   end

   return (elem)

end

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

function DeleteRotLine ( elem_id )
   /*   Loeschen eines Detailausschnitttextes                */
   /*   Eingabe:                                             */
   /*      elem_id : Attributwert fuer Attr. "ElemId"        */
   /*                                                        */
   /*   Ausgabe:                                             */
   /*      ---                                               */
   /*                                                        */
   /*  Beschreibung:                                         */

   // Suche Objekt mit Attribut in Ansicht
   elem = FindObject ("ElemId", elem_id, GROUPLine)
   if elem = 0 then
      `Element Line mit ID "`[elem_id]`" nicht gefunden` nl
      `Element kann nicht geloescht werden` nl
   else
      DeleteObject(elem)
      p1 = elem.created_by.par_p1
      p2 = elem.created_by.par_p2
   end

end

