1 (*----------------------------------------------------------------------------*)
2 (*                  Copyright (c) 2004-2010 Antrey Zubarev                    *)
3 (*----------------------------------------------------------------------------*)
4 {
5 @author(Andrey Zubarev <zamtmn@yandex.ru>)
6 }
7 
8 unit uzccomops;
9 {$INCLUDE def.inc}
10 interface
11 uses
12 
13   uzctranslations,uzeentitiesmanager,uzeentity,uzglviewareaabstract,uzgldrawcontext,
14   uzeenttext,uzctnrvectorgdbstring,uzeentityfactory,uzcsysvars,uzbstrproc,
15   uzcinterface,uzbtypesbase,uzccommandsmanager,uzclog,gzctnrvectorpobjects,
16   uzccommandsabstract,uzccommandsimpl,uzbtypes,uzcdrawings,uzeutils,uzcutils,sysutils,
17   varmandef,UGDBOpenArrayOfByte,uzeffdxf,uzegeometry,uzbmemman,uzeconsts,
18   uzccomdraw,UGDBVisibleOpenArray,uzeentline,uzbpaths,uzcshared,uzeentblockinsert,
19   uzbgeomtypes,varman,uzccablemanager,uzeentdevice,uzeentmtext,math,
20   uzcenitiesvariablesextender,uzeroot,uzglviewareadata,uzcentcable,UUnitManager,
21   gzctnrvectortypes,uzccomelectrical,URecordDescriptor,TypeDescriptors,LazLogger,
22   uzcstrconsts;
23 
24 type
25   TPlaceParam=record
26                     PlaceFirst:boolean;
27                     PlaceFirstOffset:double;
28                     PlaceLast:boolean;
29                     PlaceLastOffset:double;
30                     OtherStep:double;
31   end;
32 {Export+}
33   TInsertType=(
34                TIT_Block(*'Block'*),
35                TIT_Device(*'Device'*)
36               );
37   TOPSDatType=(
38                TOPSDT_Termo(*'Termo'*),
39                TOPSDT_Smoke(*'Smoke'*)
40               );
41   TOPSMinDatCount=(
42                    TOPSMDC_1_4(*'1 in the quarter'*),
43                    TOPSMDC_1_2(*'1 in the middle'*),
44                    TOPSMDC_2(*'2'*),
45                    TOPSMDC_3(*'3'*),
46                    TOPSMDC_4(*'4'*)
47                   );
48   TODPCountType=(
49                    TODPCT_by_Count(*'by number'*),
50                    TODPCT_by_XY(*'by width/height'*)
51                  );
52   TPlaceSensorsStrategy=(
53                   TPSS_Proportional(*'Proportional'*),
54                   TPSS_FixDD(*'Sensor-Sensor distance fix'*),
55                   TPSS_FixDW(*'Sensor-Wall distance fix'*),
56                   TPSS_ByNum(*'By number'*)
57                   );
58   TAxisReduceDistanceMode=(TARDM_Nothing(*'Nothing'*),
59                            TARDM_LongAxis(*'Long axis'*),
60                            TARDM_ShortAxis(*'Short axis'*),
61                            TARDM_AllAxis(*'All xxis'*));
62   PTOPSPlaceSmokeDetectorOrtoParam=^TOPSPlaceSmokeDetectorOrtoParam;
63   TOPSPlaceSmokeDetectorOrtoParam=packed record
64                                         InsertType:TInsertType;(*'Insert'*)
65                                         Scale:GDBDouble;(*'Plan scale'*)
66                                         ScaleBlock:GDBDouble;(*'Blocks scale'*)
67                                         StartAuto:GDBBoolean;(*'"Start" signal'*)
68                                         SensorSensorDistance:TAxisReduceDistanceMode;(*'Sensor-sensor distance reduction'*)
69                                         SensorWallDistance:TAxisReduceDistanceMode;(*'Sensor-wall distance reduction'*)
70                                         DatType:TOPSDatType;(*'Sensor type'*)
71                                         DMC:TOPSMinDatCount;(*'Min. number of sensors'*)
72                                         Height:TEnumData;(*'Height of installation'*)
73                                         ReductionFactor:GDBDouble;(*'Reduction factor'*)
74                                         NDD:GDBDouble;(*'Sensor-Sensor(standard)'*)
75                                         NDW:GDBDouble;(*'Sensor-Wall(standard)'*)
76                                         PlaceStrategy:TPlaceSensorsStrategy;
77                                         FDD:GDBDouble;(*'Sensor-Sensor(fact)'*)(*oi_readonly*)
78                                         FDW:GDBDouble;(*'Sensor-Wall(fact)'*)(*oi_readonly*)
79                                         NormalizePoint:GDBBoolean;(*'Normalize to grid (if enabled)'*)
80 
81                                         oldth:GDBInteger;(*hidden_in_objinsp*)
82                                         oldsh:GDBInteger;(*hidden_in_objinsp*)
83                                         olddt:TOPSDatType;(*hidden_in_objinsp*)
84                                   end;
85   PTOrtoDevPlaceParam=^TOrtoDevPlaceParam;
86   TOrtoDevPlaceParam=packed record
87                                         Name:GDBString;(*'Block'*)(*oi_readonly*)
88                                         ScaleBlock:GDBDouble;(*'Blocks scale'*)
89                                         CountType:TODPCountType;(*'Type of placement'*)
90                                         Count:GDBInteger;(*'Total number'*)
91                                         NX:GDBInteger;(*'Number of length'*)
92                                         NY:GDBInteger;(*'Number of width'*)
93                                         Angle:GDBDouble;(*'Rotation'*)
94                                         AutoAngle:GDBBoolean;(*'Auto rotation'*)
95                                         NormalizePoint:GDBBoolean;(*'Normalize to grid (if enabled)'*)
96 
97                      end;
98      GDBLine=packed record
99                   lBegin,lEnd:GDBvertex;
100               end;
101   OPS_SPBuild={$IFNDEF DELPHI}packed{$ENDIF} object(FloatInsert_com)
102     procedure Command(Operands:TCommandOperands); virtual;
103   end;
104 {Export-}
105 var
106    pco,pco2:pCommandRTEdObjectPlugin;
107    //pwnd:POGLWndtype;
108    t3dp: gdbvertex;
109    //pgdbinplugin: PTZCADDrawingsManager;
110    //psysvarinplugin: pgdbsysvariable;
111    pvarman:pvarmanagerdef;
112    pdw,pdd,pdtw,pdtd:PGDBDouble;
113    pdt:pinteger;
114    sdname:GDBstring;
115 
116    OPSPlaceSmokeDetectorOrtoParam:TOPSPlaceSmokeDetectorOrtoParam;
117    OrtoDevPlaceParam:TOrtoDevPlaceParam;
118 
119    OPS_SPBuild_com:OPS_SPBuild;
120 //procedure GDBGetMem({$IFDEF DEBUGBUILD}ErrGuid:pchar;{$ENDIF}var p:pointer; const size: longword); external 'cad.exe';
121 //procedure GDBFreeMem(var p: pointer); external 'cad.exe';
122 
123 //procedure HistoryOut(s: pchar); external 'cad.exe';
getprogramlognull124 //function getprogramlog:pointer; external 'cad.exe';
125 //function getcommandmanager:pointer;external 'cad.exe';
126 //function getgdb: pointer; external 'cad.exe';
127 //procedure addblockinsert(pva: PGDBObjEntityOpenArray; point: gdbvertex; scale, angle: gldouble; s: pchar);external 'cad.exe';
128 //function Vertexmorph(Vector1, Vector2: GDBVertex; a: gldouble): GDBVertex; external 'cad.exe';
129 //function VertexDmorph(Vector1, Vector2: GDBVertex; a: gldouble): GDBVertex; external 'cad.exe';
130 //function Vertexlength(Vector1, Vector2: GDBVertex): gldouble; external 'cad.exe';
131 //function Vertexangle(Vector1, Vector2: GDBVertex): gldouble; external 'cad.exe';
132 //function Vertexdmorphabs(Vector1, Vector2: GDBVertex; a: gldouble): GDBVertex; external 'cad.exe';
133 //function Vertexmorphabs(Vector1, Vector2: GDBVertex; a: gldouble): GDBVertex; external 'cad.exe';
134 //function redrawoglwnd: integer; external 'cad.exe';
135 //function getpsysvar: pointer; external 'cad.exe';
136 //function GetPZWinManager:PTZWinManager; external 'cad.exe';
137 //procedure GDBObjLineInit(own:PGDBObjGenericSubEntry;var pobjline: PGDBObjLine; layerindex, LW: smallint; p1, p2: GDBvertex); external 'cad.exe';
138 
139 //function GetPVarMan: pointer; external 'cad.exe';
140 
141 
142 //function CreateCommandRTEdObjectPlugin(ocs,oce,occ:comproc;obc,oac:commousefunc;name:pchar):pCommandRTEdObjectPlugin; external 'cad.exe';
143 {
144 //procedure builvldtable(x,y,z:gldouble);
145 
146 }
147 {procedure startup;
148 procedure finalize;}
149 
150 implementation
151 function docorrecttogrid(point:GDBVertex;need:GDBBoolean):GDBVertex;
152 var
153    gr:GDBBoolean;
154 begin
155      gr:=false;
156      if SysVar.DWG.DWG_SnapGrid<>nil then
157      if SysVar.DWG.DWG_SnapGrid^ then
158                                      gr:=true;
159      if (need and gr) then
160                           begin
161                                result:=correcttogrid(point,SysVar.DWG.DWG_Snap^);
162                                {result.x:=round((point.x-SysVar.DWG.DWG_Snap.Base.x)/SysVar.DWG.DWG_Snap.Spacing.x)*SysVar.DWG.DWG_Snap.Spacing.x+SysVar.DWG.DWG_Snap.Spacing.x;
163                                result.y:=round((point.y-SysVar.DWG.DWG_Snap.Base.y)/SysVar.DWG.DWG_Snap.Spacing.y)*SysVar.DWG.DWG_Snap.Spacing.y+SysVar.DWG.DWG_Snap.Spacing.y;
164                                result.z:=point.z;}
165                           end
166                       else
167                           result:=point;
168 end;
GetPlaceParamnull169 function GetPlaceParam(count:integer;length,sd,dd:GDBDouble;DMC:TOPSMinDatCount;ps:TPlaceSensorsStrategy):TPlaceParam;
170 begin
171      if count=2 then
172      case ps of
173  TPSS_FixDD:
174             if length<dd then
175                              ps:=TPSS_Proportional;
176  TPSS_FixDW:
177             if length<2*sd then
178                              ps:=TPSS_Proportional;
179      end;
180      case count of
181           1:begin
182               case dmc of
183                TOPSMDC_1_4:result.PlaceFirstOffset:=1/4;
184                TOPSMDC_1_2:result.PlaceFirstOffset:=1/2;
185               end;
186               result.PlaceFirst:=true;
187               result.PlaceLast:=false;
188               result.otherstep:=0;
189             end;
190           else
191             begin
192               case ps of
193     TPSS_Proportional:
194                       result.PlaceFirstOffset:=sd/(2*sd+(count-1)*dd);
195            TPSS_FixDD:
196                       result.PlaceFirstOffset:=(length-((count-1)*dd))/(2*length);
197            TPSS_FixDW:
198                       result.PlaceFirstOffset:=sd/length;
199            TPSS_ByNum:
200                       result.PlaceFirstOffset:=1/(count*2);
201               end;
202               result.PlaceLastOffset:=1-result.PlaceFirstOffset;
203               if count>2 then
204                              result.otherstep:=(result.PlaceLastOffset-result.PlaceFirstOffset)/(count-1)
205                          else
206                              result.otherstep:=0;
207               result.PlaceFirst:=true;
208               result.PlaceLast:=true;
209             end;
210      end;
211 end;
212 procedure place2(pva:PGDBObjEntityOpenArray;basepoint, dir: gdbvertex; count: integer; length,sd,dd: GDBDouble; name: pansichar;angle:GDBDouble;norm:GDBBoolean;scaleblock:GDBDouble;ps:TPlaceSensorsStrategy);
213 var //line2: gdbline;
214     i: integer;
215     d: TPlaceParam;
216 begin
217      d:=GetPlaceParam(count,length,sd,dd,OPSPlaceSmokeDetectorOrtoParam.DMC,ps);
218 
219      if d.PlaceFirst then
220      begin
221           old_ENTF_CreateBlockInsert(drawings.GetCurrentROOT,pva,
222                                      drawings.GetCurrentDWG.GetCurrentLayer,drawings.GetCurrentDWG.GetCurrentLType,sysvar.DWG.DWG_CColor^,sysvar.DWG.DWG_CLinew^,
223                                      docorrecttogrid(Vertexdmorph(basepoint, dir, d.PlaceFirstOffset),norm), scaleblock, angle, name)
224      end;
225      if d.PlaceLast then
226      begin
227           old_ENTF_CreateBlockInsert(drawings.GetCurrentROOT,pva,
228                                      drawings.GetCurrentDWG.GetCurrentLayer,drawings.GetCurrentDWG.GetCurrentLType,sysvar.DWG.DWG_CColor^,sysvar.DWG.DWG_CLinew^,
229                                      docorrecttogrid(Vertexdmorph(basepoint, dir, d.PlaceLastOffset),norm), scaleblock, angle, name)
230      end;
231      if count>2 then
232      begin
233          count := count - 2;
234          for i := 1 to count do
235          begin
236              d.PlaceFirstOffset:=d.PlaceFirstOffset+d.OtherStep;
237              old_ENTF_CreateBlockInsert(drawings.GetCurrentROOT,pva,
238                                         drawings.GetCurrentDWG.GetCurrentLayer,drawings.GetCurrentDWG.GetCurrentLType,sysvar.DWG.DWG_CColor^,sysvar.DWG.DWG_CLinew^,
239                                         docorrecttogrid(Vertexdmorph(basepoint, dir, d.PlaceFirstOffset),norm), scaleblock, angle, name)
240          end;
241      end;
242 end;
243 procedure placedatcic(pva:PGDBObjEntityOpenArray;p1, p2: gdbvertex; InitialSD, InitialDD: GDBDouble; name: pansichar;norm:GDBBoolean;scaleblock: GDBDouble;ps:TPlaceSensorsStrategy);
244 var dx, dy: GDBDouble;
245   FirstLine, SecondLine: gdbline;
246   FirstCount, SecondCount, i: integer;
247   dir: gdbvertex;
248   mincount:integer;
249   FirstLineLength,SecondLineLength:double;
250   d: TPlaceParam;
251   LongSD,LongDD: GDBDouble;
252   ShortSD,ShortDD: GDBDouble;
253 begin
254   dx := p2.x - p1.x;
255   dy := p2.y - p1.y;
256   dx := abs(dx);
257   dy := abs(dy);
258   FirstLine.lbegin := p1;
259   SecondLine.lbegin := p1;
260   if dx < dy then
261   begin
262     FirstLine.lend.x := p2.x;
263     FirstLine.lend.y := p1.y;
264     FirstLine.lend.z := 0;
265     SecondLine.lend.x := p1.x;
266     SecondLine.lend.y := p2.y;
267     SecondLine.lend.z := 0;
268   end
269   else
270   begin
271     FirstLine.lend.x := p1.x;
272     FirstLine.lend.y := p2.y;
273     FirstLine.lend.z := 0;
274     SecondLine.lend.x := p2.x;
275     SecondLine.lend.y := p1.y;
276     SecondLine.lend.z := 0;
277   end;
278   dir.x := SecondLine.lend.x - SecondLine.lbegin.x;
279   dir.y := SecondLine.lend.y - SecondLine.lbegin.y;
280   dir.z := SecondLine.lend.z - SecondLine.lbegin.z;
281 
282   LongSD:=InitialSD;
283   LongDD:=InitialDD;
284   ShortSD:=InitialSD;
285   ShortDD:=InitialDD;
286   if OPSPlaceSmokeDetectorOrtoParam.StartAuto then
287   begin
288   case OPSPlaceSmokeDetectorOrtoParam.SensorSensorDistance of
289                                             TARDM_LongAxis:LongDD:=LongDD/2;
290                                            TARDM_ShortAxis:ShortDD:=ShortDD/2;
291                                              TARDM_AllAxis:begin
292                                                             LongDD:=LongDD/2;
293                                                             ShortDD:=ShortDD/2;
294                                                            end;
295   end;
296   case OPSPlaceSmokeDetectorOrtoParam.SensorWallDistance of
297                                             TARDM_LongAxis:LongSD:=LongSD/2;
298                                            TARDM_ShortAxis:ShortSD:=ShortSD/2;
299                                              TARDM_AllAxis:begin
300                                                             LongSD:=LongSD/2;
301                                                             ShortSD:=ShortSD/2;
302                                                            end;
303   end;
304   end;
305   if (Vertexlength(FirstLine.lbegin, FirstLine.lend) - 2 * ShortSD)>0 then FirstCount := round(abs(Vertexlength(FirstLine.lbegin, FirstLine.lend) - 2 * ShortSD) / ShortDD- eps + 1.5)
306                                                          else FirstCount := 1;
307   if (Vertexlength(SecondLine.lbegin, SecondLine.lend) - 2 * LongSD)>0 then SecondCount := round(abs(Vertexlength(SecondLine.lbegin, SecondLine.lend) - 2 * LongSD) / LongDD-eps + 1.5)
308                                                          else SecondCount := 1;
309   mincount:=2;
310   case OPSPlaceSmokeDetectorOrtoParam.DMC of
311                                             TOPSMDC_1_4:mincount:=1;
312                                             TOPSMDC_1_2:mincount:=1;
313                                             TOPSMDC_3:mincount:=3;
314                                             TOPSMDC_4:mincount:=4;
315                                           end;
316   if FirstCount <= 0 then FirstCount := 1;
317   if SecondCount <= 0 then SecondCount := 1;
318   if (FirstCount*SecondCount)<mincount then
319                           begin
320                              case OPSPlaceSmokeDetectorOrtoParam.DMC of
321                                TOPSMDC_2:SecondCount:=2;
322                                TOPSMDC_3:SecondCount:=3;
323                                TOPSMDC_4:
324                                          begin
325                                               SecondCount:=2;
326                                               FirstCount:=2;
327                                          end;
328                              end;
329                          end;
330   SecondLineLength:=oneVertexlength(dir);
331   FirstLineLength:=Vertexlength(FirstLine.lbegin, FirstLine.lend);
332 
333   d:=GetPlaceParam(FirstCount,FirstLineLength,ShortSD,ShortDD,TOPSMDC_1_2,ps);
334 
335   if d.PlaceFirst then
336   begin
337        place2(pva,Vertexmorph(FirstLine.lbegin, FirstLine.lend,d.PlaceFirstOffset), dir, SecondCount, SecondLineLength,LongSD,LongDD, name,0,norm,scaleblock,ps);
338   end;
339   if d.PlaceLast then
340   begin
341        place2(pva,Vertexmorph(FirstLine.lbegin, FirstLine.lend,d.PlaceLastOffset), dir, SecondCount, SecondLineLength,LongSD,LongDD, name,0,norm,scaleblock,ps);
342   end;
343   if FirstCount>2 then
344   begin
345        FirstCount := FirstCount - 2;
346        for i := 1 to FirstCount do
347        begin
348            d.PlaceFirstOffset:=d.PlaceFirstOffset+d.OtherStep;
349            place2(pva,Vertexmorph(FirstLine.lbegin, FirstLine.lend,d.PlaceFirstOffset), dir, SecondCount, SecondLineLength,LongSD,LongDD, name,0,norm,scaleblock,ps);
350        end;
351   end;
352 
353   {case FirstCount of
354     1: begin
355           place2(pva,Vertexmorph(FirstLine.lbegin, FirstLine.lend, 0.5), dir, SecondCount, SecondLineLength,LongSD,LongDD, name,0,norm,scaleblock,ps);
356        end;
357     2: begin
358         if ((Vertexlength(FirstLine.lbegin, FirstLine.lend) - 2 * LongSD)<LongDD) then
359         begin
360           place2(pva,Vertexmorph(FirstLine.lbegin, FirstLine.lend, 1 / 4), dir, SecondCount, SecondLineLength,LongSD,LongDD, name,0,norm,scaleblock,ps);
361           place2(pva,Vertexmorph(FirstLine.lbegin, FirstLine.lend, 3 / 4), dir, SecondCount, SecondLineLength,LongSD,LongDD, name,0,norm,scaleblock,ps);
362         end
363         else
364           begin
365           place2(pva,Vertexmorphabs2(FirstLine.lbegin, FirstLine.lend, LongSD), dir, SecondCount, SecondLineLength,LongSD,LongDD, name,0,norm,scaleblock,ps);
366           place2(pva,Vertexmorphabs2(FirstLine.lbegin, FirstLine.lend, -LongSD), dir, SecondCount, SecondLineLength,LongSD,LongDD, name,0,norm,scaleblock,ps);
367         end
368        end
369   else begin
370           place2(pva,Vertexmorphabs2(FirstLine.lbegin, FirstLine.lend, LongSD), dir, SecondCount, SecondLineLength,LongSD,LongDD, name,0,norm,scaleblock,OPSPlaceSmokeDetectorOrtoParam.PlaceStrategy);
371           place2(pva,Vertexmorphabs2(FirstLine.lbegin, FirstLine.lend, -LongSD), dir, SecondCount, SecondLineLength,LongSD,LongDD, name,0,norm,scaleblock,OPSPlaceSmokeDetectorOrtoParam.PlaceStrategy);
372           SecondLine.lbegin := Vertexmorphabs2(FirstLine.lbegin, FirstLine.lend, LongSD);
373           SecondLine.lend := Vertexmorphabs2(FirstLine.lbegin, FirstLine.lend, -LongSD);
374           FirstCount:=FirstCount-2;
375           for i := 1 to FirstCount do place2(pva,Vertexmorph(SecondLine.lbegin, SecondLine.lend, i / (FirstCount + 1)), dir, SecondCount, SecondLineLength,LongSD,LongDD, name,0,norm,scaleblock,OPSPlaceSmokeDetectorOrtoParam.PlaceStrategy);
376        end
377   end;}
378 end;
CommandStartnull379 function CommandStart(operands:pansichar):GDBInteger;
380 begin
381   drawings.AddBlockFromDBIfNeed(drawings.GetCurrentDWG,'DEVICE_PS_DAT_SMOKE');
382   drawings.AddBlockFromDBIfNeed(drawings.GetCurrentDWG,'DEVICE_PS_DAT_TERMO');
383   drawings.GetCurrentDWG.wa.SetMouseMode((MGet3DPoint) or (MMoveCamera));
384   ZCMsgCallBackInterface.TextMessage(rscmFirstCorner,TMWOHistoryOut);
385   zcShowCommandParams(SysUnit.TypeName2PTD('CommandRTEdObject'),pco);
386   result:=cmd_ok;
387 end;
BeforeClicknull388 function BeforeClick(wc: GDBvertex; mc: GDBvertex2DI; var button: GDBByte;osp:pos_record;mclick:GDBInteger): integer;
389 begin
390   result:=mclick;
391   if (button and MZW_LBUTTON)<>0 then
392     //if pco^.mouseclic = 1 then
393     begin
394       ZCMsgCallBackInterface.TextMessage(rscmSecondCorner,TMWOHistoryOut);
395       t3dp:=wc;
396     end;
397 end;
AfterClicknull398 function AfterClick(wc: GDBvertex; mc: GDBvertex2DI; var button: GDBByte;osp:pos_record;mclick:GDBInteger):GDBInteger;
399 var
400 pl:pgdbobjline;
401 //debug:string;
402 dw,dd:gdbdouble;
403 DC:TDrawContext;
404 begin
405 
406 
407   dw:=OPSPlaceSmokeDetectorOrtoParam.NDW/OPSPlaceSmokeDetectorOrtoParam.Scale;
408   dd:=OPSPlaceSmokeDetectorOrtoParam.NDD/OPSPlaceSmokeDetectorOrtoParam.Scale;
409   if OPSPlaceSmokeDetectorOrtoParam.ReductionFactor<>0 then
410   begin
411        dw:=dw*OPSPlaceSmokeDetectorOrtoParam.ReductionFactor;
412        dd:=dd*OPSPlaceSmokeDetectorOrtoParam.ReductionFactor;
413   end;
414   {if drawings.GetCurrentDWG.BlockDefArray.getindex(@sdname[1])<0 then
415                                                          begin
416                                                               sdname:=sdname;
417                                                               //drawings.GetCurrentDWG.BlockDefArray.loadblock(pansichar(sysinfo.sysparam.programpath+'blocks\ops\'+sdname+'.dxf'),@sdname[1],drawings.GetCurrentDWG)
418                                                          end;}
419   result:=mclick;
420   drawings.GetCurrentDWG.ConstructObjRoot.ObjArray.free;
421 
422   pl := PGDBObjLine(ENTF_CreateLine(@drawings.GetCurrentDWG.ConstructObjRoot,@drawings.GetCurrentDWG^.ConstructObjRoot.ObjArray,[t3dp.x,t3dp.y,t3dp.z,wc.x,wc.y,wc.z]));
423   zcSetEntPropFromCurrentDrawingProp(pl);
424 
425   //pl := pointer(drawings.GetCurrentDWG.ConstructObjRoot.ObjArray.CreateObj(GDBLineID{,drawings.GetCurrentROOT}));
426   //GDBObjLineInit(drawings.GetCurrentROOT,pl, drawings.GetCurrentDWG.LayerTable.GetCurrentLayer,sysvar.dwg.DWG_CLinew^, t3dp, wc);
427   dc:=drawings.GetCurrentDWG^.CreateDrawingRC;
428   pl^.Formatentity(drawings.GetCurrentDWG^,dc);
429   if (button and MZW_LBUTTON)=0 then
430   begin
431        placedatcic(@drawings.GetCurrentDWG.ConstructObjRoot.ObjArray,gdbobjline(pl^).CoordInWCS.lbegin, gdbobjline(pl^).CoordInWCS.lend, dw, dd,@sdname[1],OPSPlaceSmokeDetectorOrtoParam.NormalizePoint,OPSPlaceSmokeDetectorOrtoParam.ScaleBlock,OPSPlaceSmokeDetectorOrtoParam.PlaceStrategy);
432   end
433   else
434   begin
435        result:=-1;
436        //pco^.mouseclic:=-1;
437        //drawings.GetCurrentDWG.ConstructObjRoot.cleareraseobj;
438        placedatcic(@drawings.GetCurrentROOT.ObjArray,gdbobjline(pl^).CoordInWCS.lbegin, gdbobjline(pl^).CoordInWCS.lend, dw, dd,@sdname[1],OPSPlaceSmokeDetectorOrtoParam.NormalizePoint,OPSPlaceSmokeDetectorOrtoParam.ScaleBlock,OPSPlaceSmokeDetectorOrtoParam.PlaceStrategy);
439        drawings.GetCurrentDWG.ConstructObjRoot.ObjArray.free;
440 
441        drawings.GetCurrentROOT.calcbb(dc);
442        zcRedrawCurrentDrawing;
443        ZCMsgCallBackInterface.TextMessage(rscmFirstCorner,TMWOHistoryOut);
444        //commandend;
445        //pcommandmanager^.executecommandend;
446   end;
447 //  if button = 1 then
448 //  begin
449 //    pgdbinplugin^.ObjArray.add(addr(pc));
450 //    pgdbinplugin^.ConstructObjRoot.Count := 0;
451 //    commandend;
452 //    executecommandend;
453 //  end;
454 end;
455 procedure commformat;
456 var s:GDBString;
457     pcfd:PRecordDescriptor;
458     pf:PfieldDescriptor;
459 begin
460   pcfd:=pointer(SysUnit.TypeName2PTD('TOPSPlaceSmokeDetectorOrtoParam'));
461   if pcfd<>nil then
462   begin
463   pf:=pcfd^.FindField('SensorSensorDistance');
464   if pf<>nil then
465                  begin
466                     if OPSPlaceSmokeDetectorOrtoParam.StartAuto then
467                                                                     pf^.base.Attributes:=pf.base.Attributes and (not FA_READONLY)
468                                                                 else
469                                                                     pf^.base.Attributes:=pf.base.Attributes or FA_READONLY;
470                  end;
471   pf:=pcfd^.FindField('SensorWallDistance');
472   if pf<>nil then
473                  begin
474                     if OPSPlaceSmokeDetectorOrtoParam.StartAuto then
475                                                                     pf^.base.Attributes:=pf.base.Attributes and (not FA_READONLY)
476                                                                 else
477                                                                     pf^.base.Attributes:=pf.base.Attributes or FA_READONLY;
478                  end;
479   end;
480      sdname:=sdname;
481      if OPSPlaceSmokeDetectorOrtoParam.DatType<>OPSPlaceSmokeDetectorOrtoParam.olddt then
482      begin
483           OPSPlaceSmokeDetectorOrtoParam.olddt:=OPSPlaceSmokeDetectorOrtoParam.DatType;
484           OPSPlaceSmokeDetectorOrtoParam.Height.Enums.clear;
485           case OPSPlaceSmokeDetectorOrtoParam.DatType of
486                TOPSDT_Smoke:begin
487                                  s:='До 3,5м';
488                                  OPSPlaceSmokeDetectorOrtoParam.Height.Enums.PushBackData(s);
489                                  s:='Св. 3,5 до 6,0';
490                                  OPSPlaceSmokeDetectorOrtoParam.Height.Enums.PushBackData(s);
491                                  s:='Св. 6,0 до 10,0';
492                                  OPSPlaceSmokeDetectorOrtoParam.Height.Enums.PushBackData(s);
493                                  s:='Св. 10,5 до 12,0';
494                                  OPSPlaceSmokeDetectorOrtoParam.Height.Enums.PushBackData(s);
495                                  s:='Не норм.';
496                                  OPSPlaceSmokeDetectorOrtoParam.Height.Enums.PushBackData(s);
497                                  OPSPlaceSmokeDetectorOrtoParam.oldth:=OPSPlaceSmokeDetectorOrtoParam.Height.Selected;
498                                  OPSPlaceSmokeDetectorOrtoParam.Height.Selected:=OPSPlaceSmokeDetectorOrtoParam.oldsh;
499                             end;
500                TOPSDT_Termo:begin
501                                  s:='До 3,5м';
502                                  OPSPlaceSmokeDetectorOrtoParam.Height.Enums.PushBackData(s);
503                                  s:='Св. 3,5 до 6,0';
504                                  OPSPlaceSmokeDetectorOrtoParam.Height.Enums.PushBackData(s);
505                                  s:='Св. 6,0 до 9,0';
506                                  OPSPlaceSmokeDetectorOrtoParam.Height.Enums.PushBackData(s);
507                                  s:='Не норм.';
508                                  OPSPlaceSmokeDetectorOrtoParam.Height.Enums.PushBackData(s);
509                                  OPSPlaceSmokeDetectorOrtoParam.oldsh:=OPSPlaceSmokeDetectorOrtoParam.Height.Selected;
510                                  OPSPlaceSmokeDetectorOrtoParam.Height.Selected:=OPSPlaceSmokeDetectorOrtoParam.oldth;
511                             end;
512           end;
513      end;
514      case OPSPlaceSmokeDetectorOrtoParam.DatType of
515           TOPSDT_Smoke:begin
516                             case OPSPlaceSmokeDetectorOrtoParam.Height.Selected of
517                                0:begin
518                                       OPSPlaceSmokeDetectorOrtoParam.NDW:=4500;
519                                       OPSPlaceSmokeDetectorOrtoParam.NDD:=9000;
520                                  end;
521                                1:begin
522                                       OPSPlaceSmokeDetectorOrtoParam.NDW:=4000;
523                                       OPSPlaceSmokeDetectorOrtoParam.NDD:=8500;
524                                  end;
525                                2:begin
526                                       OPSPlaceSmokeDetectorOrtoParam.NDW:=4000;
527                                       OPSPlaceSmokeDetectorOrtoParam.NDD:=8000;
528                                  end;
529                                3:begin
530                                       OPSPlaceSmokeDetectorOrtoParam.NDW:=3500;
531                                       OPSPlaceSmokeDetectorOrtoParam.NDD:=7500;
532                                  end;
533                            end;
534                                {if (OPSPlaceSmokeDetectorOrtoParam.Height.Selected<>4)and OPSPlaceSmokeDetectorOrtoParam.StartAuto then
535                                begin
536                                     OPSPlaceSmokeDetectorOrtoParam.NDW:=OPSPlaceSmokeDetectorOrtoParam.NDW/2;
537                                     OPSPlaceSmokeDetectorOrtoParam.NDD:=OPSPlaceSmokeDetectorOrtoParam.NDD/2;
538                                end;}
539                            sdname:='PS_DAT_SMOKE';
540                      end;
541           TOPSDT_Termo:begin
542                case OPSPlaceSmokeDetectorOrtoParam.Height.Selected of
543                                0:begin
544                                       OPSPlaceSmokeDetectorOrtoParam.NDW:=2500;
545                                       OPSPlaceSmokeDetectorOrtoParam.NDD:=5000;
546                                  end;
547                                1:begin
548                                       OPSPlaceSmokeDetectorOrtoParam.NDW:=2000;
549                                       OPSPlaceSmokeDetectorOrtoParam.NDD:=4500;
550                                  end;
551                                2:begin
552                                       OPSPlaceSmokeDetectorOrtoParam.NDW:=2000;
553                                       OPSPlaceSmokeDetectorOrtoParam.NDD:=4000;
554                                  end;
555                end;
556                                {if (OPSPlaceSmokeDetectorOrtoParam.Height.Selected<>3)and OPSPlaceSmokeDetectorOrtoParam.StartAuto then
557                                begin
558                                     OPSPlaceSmokeDetectorOrtoParam.NDW:=OPSPlaceSmokeDetectorOrtoParam.NDW/2;
559                                     OPSPlaceSmokeDetectorOrtoParam.NDD:=OPSPlaceSmokeDetectorOrtoParam.NDD/2;
560                                end;}
561                sdname:='PS_DAT_TERMO';
562                             end;
563      end;
564     if OPSPlaceSmokeDetectorOrtoParam.InsertType=TIT_Device then
565                                                                 sdname:=DevicePrefix+sdname;
566 end;
567 {function OPS_Sensor_Mark_com(Operands:pansichar):GDBInteger;
568 var i: GDBInteger;
569     pcable:pGDBObjCable;
570     ir,ir_inNodeArray:itrec;
571     pvd:pvardesk;
572     currentunit:TUnit;
573     ucount:gdbinteger;
574     ptn:PTNodeProp;
575     p:pointer;
576     cman:TCableManager;
577 begin
578   if drawings.GetCurrentDWG.ObjRoot.ObjArray.Count = 0 then exit;
579   cman.init;
580   cman.build;
581   cman.done;
582 
583   currentunit.init('calc');
584   units.loadunit(expandpath('*rtl\objcalc\opsmarkdef.pas'),(@currentunit));
585   pcable:=gdb.GetCurrentDWG.ObjRoot.ObjArray.beginiterate(ir);
586   if pcable<>nil then
587   repeat
588         if pcable^.GetObjType=GDBCableID then
589         begin
590              pvd:=currentunit.FindVariable('CDC_temp');
591              pgdbinteger(pvd.data.Instance)^:=0;
592              pvd:=currentunit.FindVariable('CDSC_temp');
593              pgdbinteger(pvd.data.Instance)^:=0;
594              p:=@pcable.ou;
595              currentunit.InterfaceUses.addnodouble(@p);
596              ucount:=currentunit.InterfaceUses.Count;
597 
598 
599 
600 
601 
602              ptn:=pcable^.NodePropArray.beginiterate(ir_inNodeArray);
603              if ptn<>nil then
604                 repeat
605                     if ptn^.DevLink<>nil then
606                     begin
607                          p:=@ptn^.DevLink^.bp.Owner.ou;
608                          currentunit.InterfaceUses.addnodouble(@p);
609 
610                          units.loadunit(expandpath('*rtl\objcalc\opsmark.pas'),(@currentunit));
611 
612                          dec(currentunit.InterfaceUses.Count);
613 
614                          ptn^.DevLink^.bp.Owner^.Format;
615                      end;
616 
617                     ptn:=pcable^.NodePropArray.iterate(ir_inNodeArray);
618                 until ptn=nil;
619 
620 
621 
622 
623              currentunit.InterfaceUses.Count:=ucount-1;
624         end;
625   pcable:=drawings.GetCurrentDWG.ObjRoot.ObjArray.iterate(ir);
626   until pcable=nil;
627 
628   currentunit.done;
629   redrawoglwnd;
630   result:=cmd_ok;
631 end;}
OPS_Sensor_Mark_comnull632 function OPS_Sensor_Mark_com(operands:TCommandOperands):TCommandResult;
633 var //i: GDBInteger;
634     pcabledesk:PTCableDesctiptor;
635     ir,ir2,ir_inNodeArray:itrec;
636     pvd:pvardesk;
637     defaultunit:TUnit;
638     currentunit:PTUnit;
639     UManager:TUnitManager;
640     ucount:gdbinteger;
641     ptn:PGDBObjDevice;
642     p:pointer;
643     cman:TCableManager;
644     SaveEntUName,SaveCabUName:gdbstring;
645     cablemetric,devicemetric,numingroupmetric:GDBString;
646     ProcessedDevices:TZctnrVectorPGDBaseObjects;
647     name:gdbstring;
648     DC:TDrawContext;
649     pcablestartsegmentvarext,pptnownervarext:PTVariablesExtender;
650 const
651       DefNumMetric='default_num_in_group';
GetNumUnitnull652 function GetNumUnit(uname:gdbstring):PTUnit;
653 begin
654      //result:=nil;
655      result:=UManager.internalfindunit(uname);
656      if result=nil then
657      begin
658           result:=pointer(UManager.CreateObject);
659           result.init(uname);
660           result.CopyFrom(@defaultunit);
661      end;
662 end;
663 
664 begin
665   dc:=drawings.GetCurrentDWG^.CreateDrawingRC;
666   if drawings.GetCurrentROOT.ObjArray.Count = 0 then exit;
667   ProcessedDevices.init({$IFDEF DEBUGBUILD}'{518968B6-90DE-4895-A27C-B28234A6DC17}',{$ENDIF}100);
668   cman.init;
669   cman.build;
670   UManager.init;
671 
672   defaultunit.init(DefNumMetric);
673   units.loadunit(SupportPath,InterfaceTranslate,expandpath('*rtl/objcalc/opsmarkdef.pas'),(@defaultunit));
674   pcabledesk:=cman.beginiterate(ir);
675   if pcabledesk<>nil then
676   repeat
677         begin
678             pcablestartsegmentvarext:=pcabledesk.StartSegment^.GetExtension(typeof(TVariablesExtender));
679             //pvd:=PTObjectUnit(pcabledesk.StartSegment.ou.Instance)^.FindVariable('GC_Metric');
680             pvd:=pcablestartsegmentvarext^.entityunit.FindVariable('GC_Metric');
681             if pvd<>nil then
682                             begin
683                                  cablemetric:=pvd.data.PTD.GetValueAsString(pvd.data.Instance);
684                             end
685                         else
686                             begin
687                                  cablemetric:='';
688                             end;
689 
690              currentunit:=Umanager.beginiterate(ir2);
691              if currentunit<>nil then
692              repeat
693              pvd:=currentunit.FindVariable('CDC_temp');
694              pgdbinteger(pvd.data.Instance)^:=0;
695              pvd:=currentunit.FindVariable('CDSC_temp');
696              pgdbinteger(pvd.data.Instance)^:=1;
697              currentunit:=Umanager.iterate(ir2);
698              until currentunit=nil;
699              currentunit:=nil;
700 
701 
702 
703 
704 
705              ptn:=pcabledesk^.Devices.beginiterate(ir_inNodeArray);
706              if ptn<>nil then
707                 repeat
708                     begin
709                         pptnownervarext:=ptn^.bp.ListPos.Owner^.GetExtension(typeof(TVariablesExtender));
710                         //pvd:=PTObjectUnit(ptn^.bp.ListPos.Owner.ou.Instance)^.FindVariable('GC_Metric');
711                         pvd:=pptnownervarext^.entityunit.FindVariable('GC_Metric');
712                         if pvd<>nil then
713                                         begin
714                                              devicemetric:=pvd.data.PTD.GetValueAsString(pvd.data.Instance);
715                                         end
716                                     else
717                                         begin
718                                              devicemetric:='';
719                                         end;
720                         //pvd:=PTObjectUnit(ptn^.bp.ListPos.Owner.ou.Instance)^.FindVariable('GC_InGroup_Metric');
721                         pvd:=pptnownervarext^.entityunit.FindVariable('GC_InGroup_Metric');
722                                         if pvd<>nil then
723                                                         begin
724                                                              numingroupmetric:=pvd.data.PTD.GetValueAsString(pvd.data.Instance);
725                                                              if numingroupmetric='' then
726                                                                                         numingroupmetric:=DefNumMetric;
727 
728                                                         end
729                                                     else
730                                                         begin
731                                                              numingroupmetric:=DefNumMetric;
732                                                         end;
733                         if devicemetric=cablemetric then
734                         begin
735                         if ProcessedDevices.IsDataExist(@ptn^.bp.ListPos.Owner^)=-1 then
736                     begin
737                          currentunit:=GetNumUnit(numingroupmetric);
738 
739                          SaveCabUName:=pcablestartsegmentvarext^.entityunit.Name;
740                          pcablestartsegmentvarext^.entityunit.Name:='Cable';
741                          p:=@pcablestartsegmentvarext^.entityunit;
742                          currentunit.InterfaceUses.PushBackIfNotPresent(p);
743                          ucount:=currentunit.InterfaceUses.Count;
744 
745                          SaveEntUName:=pptnownervarext^.entityunit.Name;
746                          pptnownervarext^.entityunit.Name:='Entity';
747                          p:=@pptnownervarext^.entityunit;
748                          currentunit.InterfaceUses.PushBackIfNotPresent(p);
749 
750                          units.loadunit(SupportPath,InterfaceTranslate,expandpath('*rtl/objcalc/opsmark.pas'),(currentunit));
751 
752                          ProcessedDevices.PushBackData(ptn^.bp.ListPos.Owner);
753 
754                          dec(currentunit.InterfaceUses.Count,2);
755 
756                          pptnownervarext^.entityunit.Name:=SaveEntUName;
757                          pcablestartsegmentvarext^.entityunit.Name:=SaveCabUName;
758 
759                          PGDBObjLine(ptn^.bp.ListPos.Owner)^.Formatentity(drawings.GetCurrentDWG^,dc);
760                     end
761                         else
762                             begin
763                             pvd:=pptnownervarext^.entityunit.FindVariable('NMO_Name');
764                             if pvd<>nil then
765                                         begin
766                                              name:='"'+pvd.data.PTD.GetValueAsString(pvd.data.Instance)+'"';
767                                         end
768                                     else
769                                         begin
770                                              name:='"без имени"';
771                                         end;
772                             ZCMsgCallBackInterface.TextMessage(format('Попытка повторной нумерации устройства %s кабелем (сегментом кабеля) %s',[name,'"'+pcabledesk^.Name+'"']),TMWOHistoryOut);
773                             end;
774                         end;
775 
776                     end;
777                     //ptn^.bp.ListPos.Owner.ou.Name:=SaveEntUName;
778                     ptn:=pcabledesk^.Devices.iterate(ir_inNodeArray);
779                 until ptn=nil;
780 
781 
782 
783              if currentunit<>nil then
784              currentunit.InterfaceUses.Count:=ucount-1;
785         end;
786   pcablestartsegmentvarext^.entityunit.Name:=SaveCabUName;
787   pcabledesk:=cman.iterate(ir);
788   until pcabledesk=nil;
789 
790   defaultunit.done;
791   UManager.done;
792   cman.done;
793   ProcessedDevices.Clear;
794   ProcessedDevices.Done;
795   zcRedrawCurrentDrawing;
796   result:=cmd_ok;
797 end;
798 procedure InsertDat2(datname,name:GDBString;var currentcoord:GDBVertex; var root:GDBObjRoot);
799 var
800    pv:pGDBObjDevice;
801    pt:pGDBObjMText;
802    lx,{rx,}uy,dy:GDBDouble;
803    tv:gdbvertex;
804    DC:TDrawContext;
805 begin
806           name:=uzbstrproc.Tria_Utf8ToAnsi(name);
807 
808      drawings.AddBlockFromDBIfNeed(drawings.GetCurrentDWG,datname);
809      pointer(pv):=old_ENTF_CreateBlockInsert(drawings.GetCurrentROOT,@{drawings.GetCurrentROOT}root.ObjArray,
810                                          drawings.GetCurrentDWG.GetCurrentLayer,drawings.GetCurrentDWG.GetCurrentLType,sysvar.DWG.DWG_CColor^,sysvar.DWG.DWG_CLinew^,
811                                          currentcoord, 1, 0,@datname[1]);
812      dc:=drawings.GetCurrentDWG^.CreateDrawingRC;
813      zcSetEntPropFromCurrentDrawingProp(pv);
814      pv^.formatentity(drawings.GetCurrentDWG^,dc);
815      pv^.getoutbound(dc);
816 
817      lx:=pv.P_insert_in_WCS.x-pv.vp.BoundingBox.LBN.x;
818      //rx:=pv.vp.BoundingBox.RTF.x-pv.P_insert_in_WCS.x;
819      dy:=pv.P_insert_in_WCS.y-pv.vp.BoundingBox.LBN.y;
820      uy:=pv.vp.BoundingBox.RTF.y-pv.P_insert_in_WCS.y;
821 
822      pv^.Local.P_insert.y:=pv^.Local.P_insert.y+dy;
823      pv^.Formatentity(drawings.GetCurrentDWG^,dc);
824 
825      tv:=currentcoord;
826      tv.x:=tv.x-lx-1;
827      tv.y:=tv.y+(dy+uy)/2;
828 
829      if name<>'' then
830      begin
831      pt:=pointer(AllocEnt(GDBMtextID));
832      pt^.init({drawings.GetCurrentROOT}@root,sysvar.dwg.DWG_CLayer^,sysvar.dwg.DWG_CLinew^,name,tv,2.5,0,0.65,RightAngle,jsbc,1,1);
833      pt^.TXTStyleIndex:=pointer(drawings.GetCurrentDWG.GetTextStyleTable^.getDataMutable(0));
834      root.ObjArray.AddPEntity(pt^);
835      zcSetEntPropFromCurrentDrawingProp(pt);
836      pt^.vp.Layer:=drawings.GetCurrentDWG.LayerTable.getAddres('TEXT');
837      pt^.Formatentity(drawings.GetCurrentDWG^,dc);
838      end;
839 
840      currentcoord.y:=currentcoord.y+dy+uy;
841 end;
InsertDatnull842 function InsertDat(datname,sname,ename:GDBString;datcount:GDBInteger;var currentcoord:GDBVertex; var root:GDBObjRoot):pgdbobjline;
843 var
844 //   pv:pGDBObjDevice;
845 //   lx,rx,uy,dy:GDBDouble;
846    pl:pgdbobjline;
847    oldcoord,oldcoord2:gdbvertex;
848    DC:TDrawContext;
849 begin
850      dc:=drawings.GetCurrentDWG^.CreateDrawingRC;
851      if datcount=1 then
852                     InsertDat2(datname,sname,currentcoord,root)
853 else if datcount>1 then
854                     begin
855                          InsertDat2(datname,sname,currentcoord,root);
856                          oldcoord:=currentcoord;
857                          currentcoord.y:=currentcoord.y+10;
858                          oldcoord2:=currentcoord;
859                          InsertDat2(datname,ename,currentcoord,root);
860                     end;
861      if datcount=2 then
862                        begin
863                          pl:=pointer(AllocEnt(GDBLineID));
864                          pl^.init({drawings.GetCurrentROOT}@root,drawings.GetCurrentDWG.GetCurrentLayer,sysvar.dwg.DWG_CLinew^,oldcoord,oldcoord2);
865                          root.ObjArray.AddPEntity(pl^);
866                          zcSetEntPropFromCurrentDrawingProp(pl);
867                          pl^.Formatentity(drawings.GetCurrentDWG^,dc);
868                        end
869 else if datcount>2 then
870                        begin
871                          pl:=pointer(AllocEnt(GDBLineID));
872                          pl^.init({drawings.GetCurrentROOT}@root,drawings.GetCurrentDWG.GetCurrentLayer,sysvar.dwg.DWG_CLinew^,oldcoord, Vertexmorphabs2(oldcoord,oldcoord2,2));
873                          root.ObjArray.AddPEntity(pl^);
874                          zcSetEntPropFromCurrentDrawingProp(pl);
875                          pl^.Formatentity(drawings.GetCurrentDWG^,dc);
876                          pl:=pointer(AllocEnt(GDBLineID));
877                          pl^.init({drawings.GetCurrentROOT}@root,drawings.GetCurrentDWG.GetCurrentLayer,sysvar.dwg.DWG_CLinew^,Vertexmorphabs2(oldcoord,oldcoord2,4), Vertexmorphabs2(oldcoord,oldcoord2,6));
878                          root.ObjArray.AddPEntity(pl^);
879                          zcSetEntPropFromCurrentDrawingProp(pl);
880                          pl^.Formatentity(drawings.GetCurrentDWG^,dc);
881                          pl:=pointer(AllocEnt(GDBLineID));
882                          pl^.init({drawings.GetCurrentROOT}@root,drawings.GetCurrentDWG.GetCurrentLayer,sysvar.dwg.DWG_CLinew^,Vertexmorphabs2(oldcoord,oldcoord2,8), oldcoord2);
883                          root.ObjArray.AddPEntity(pl^);
884                          zcSetEntPropFromCurrentDrawingProp(pl);
885                          pl^.Formatentity(drawings.GetCurrentDWG^,dc);
886                        end;
887 
888      oldcoord:=currentcoord;
889      currentcoord.y:=currentcoord.y+10;
890      pl:=pointer(AllocEnt(GDBLineID));
891      pl^.init({drawings.GetCurrentROOT}@root,drawings.GetCurrentDWG.GetCurrentLayer,sysvar.dwg.DWG_CLinew^,oldcoord,currentcoord);
892      root.ObjArray.AddPEntity(pl^);
893      zcSetEntPropFromCurrentDrawingProp(pl);
894      pl^.Formatentity(drawings.GetCurrentDWG^,dc);
895      result:=pl;
896 end;
897 procedure OPS_SPBuild.Command(Operands:TCommandOperands);
OPS_SPBuild_comnull898 //function OPS_SPBuild_com(Operands:pansichar):GDBInteger;
899 var count: GDBInteger;
900     pcabledesk:PTCableDesctiptor;
901     PCableSS:PGDBObjCable;
902     ir,ir_inNodeArray:itrec;
903     pvd:pvardesk;
904 //    currentunit:TUnit;
905 //    ucount:gdbinteger;
906 //    ptn:PGDBObjDevice;
907 //    p:pointer;
908     cman:TCableManager;
909     pv:pGDBObjDevice;
910 
911     coord,currentcoord:GDBVertex;
912 //    pbd:PGDBObjBlockdef;
913     {pvn,pvm,}pvmc{,pvl}:pvardesk;
914 
915     nodeend,nodestart:PGDBObjDevice;
916     isfirst:boolean;
917     startmat,endmat,startname,endname,prevname:gdbstring;
918 
919     //cmlx,cmrx,cmuy,cmdy:gdbdouble;
920     {lx,rx,}uy,dy:gdbdouble;
921     lsave:{integer}PGDBPointer;
922     DC:TDrawContext;
923     pCableSSvarext,ppvvarext,pnodeendvarext:PTVariablesExtender;
924 begin
925   if drawings.GetCurrentROOT.ObjArray.Count = 0 then exit;
926   dc:=drawings.GetCurrentDWG^.CreateDrawingRC;
927   cman.init;
928   cman.build;
929 
930          drawings.GetCurrentDWG.wa.SetMouseMode((MGet3DPoint) or (MMoveCamera) or (MRotateCamera));
931 
932   coord:=uzegeometry.NulVertex;
933   coord.y:=0;
934   coord.x:=0;
935   prevname:='';
936   pcabledesk:=cman.beginiterate(ir);
937   if pcabledesk<>nil then
938   repeat
939         PCableSS:=pcabledesk^.StartSegment;
940         pCableSSvarext:=PCableSS^.GetExtension(typeof(TVariablesExtender));
941         //pvd:=PTObjectUnit(PCableSS.ou.Instance)^.FindVariable('CABLE_Type');     { TODO : Сделать поиск переменных caseнезависимым }
942         pvd:=pCableSSvarext^.entityunit.FindVariable('CABLE_Type');
943 
944         if pvd<>nil then
945         begin
946              //if PTCableType(pvd^.data.Instance)^=TCT_ShleifOPS then
947              if (pcabledesk.StartDevice<>nil){and(pcabledesk.EndDevice<>nil)} then
948              begin
949                   ZCMsgCallBackInterface.TextMessage(pcabledesk.Name,TMWOHistoryOut);
950                   //programlog.logoutstr(pcabledesk.Name,0);
951                   currentcoord:=coord;
952                   PTCableType(pvd^.data.Instance)^:=TCT_ShleifOPS;
953                   lsave:=SysVar.dwg.DWG_CLayer^;
954                   SysVar.dwg.DWG_CLayer^:=drawings.GetCurrentDWG.LayerTable.GetSystemLayer;
955 
956                   drawings.AddBlockFromDBIfNeed(drawings.GetCurrentDWG,'DEVICE_CABLE_MARK');
957                   pointer(pv):=old_ENTF_CreateBlockInsert(@drawings.GetCurrentDWG.ConstructObjRoot,@{drawings.GetCurrentROOT.ObjArray}drawings.GetCurrentDWG.ConstructObjRoot.ObjArray,
958                                                       drawings.GetCurrentDWG.GetCurrentLayer,drawings.GetCurrentDWG.GetCurrentLType,sysvar.DWG.DWG_CColor^,sysvar.DWG.DWG_CLinew^,
959                                                       currentcoord, 1, 0,'DEVICE_CABLE_MARK');
960                   zcSetEntPropFromCurrentDrawingProp(pv);
961 
962                   SysVar.dwg.DWG_CLayer^:=lsave;
963                   ppvvarext:=pv^.GetExtension(typeof(TVariablesExtender));
964                   //pvmc:=PTObjectUnit(pv^.ou.Instance)^.FindVariable('CableName');
965                   pvmc:=ppvvarext^.entityunit.FindVariable('CableName');
966                   if pvmc<>nil then
967                   begin
968                       pstring(pvmc^.data.Instance)^:=pcabledesk.Name;
969                   end;
970                   Cable2CableMark(pcabledesk,pv);
971                   pv^.formatentity(drawings.GetCurrentDWG^,dc);
972                   pv^.getoutbound(dc);
973 
974                   //lx:=pv.P_insert_in_WCS.x-pv.vp.BoundingBox.LBN.x;
975                   //rx:=pv.vp.BoundingBox.RTF.x-pv.P_insert_in_WCS.x;
976                   dy:=pv.P_insert_in_WCS.y-pv.vp.BoundingBox.LBN.y;
977                   uy:=pv.vp.BoundingBox.RTF.y-pv.P_insert_in_WCS.y;
978 
979                   pv^.Local.P_insert.y:=pv^.Local.P_insert.y+dy;
980                   pv^.Formatentity(drawings.GetCurrentDWG^,dc);
981                   currentcoord.y:=currentcoord.y+dy+uy;
982 
983 
984                   isfirst:=true;
985                   {nodeend:=}pcabledesk^.Devices.beginiterate(ir_inNodeArray);
986                   nodeend:=pcabledesk^.Devices.iterate(ir_inNodeArray);
987                   nodestart:=nil;
988                   count:=0;
989                   if nodeend<>nil then
990                   repeat
991                         if nodeend^.bp.ListPos.Owner<>pointer(drawings.GetCurrentROOT) then
992                                                                           nodeend:=pointer(nodeend^.bp.ListPos.Owner);
993                         pnodeendvarext:=nodeend^.GetExtension(typeof(TVariablesExtender));
994                         //pvd:=PTObjectUnit(nodeend^.ou.Instance)^.FindVariable('NMO_Name');
995                         pvd:=pnodeendvarext^.entityunit.FindVariable('NMO_Name');
996                         if pvd<>nil then
997                         begin
998                              //endname:=pstring(pvd^.data.Instance)^;
999                              endname:=pvd^.data.PTD.GetValueAsString(pvd^.data.Instance);
1000                         end
1001                            else endname:='';
1002                         //pvd:=PTObjectUnit(nodeend^.ou.Instance)^.FindVariable('DB_link');
1003                         pvd:=pnodeendvarext^.entityunit.FindVariable('DB_link');
1004                         if pvd<>nil then
1005                         begin
1006                             //endmat:=pstring(pvd^.data.Instance)^;
1007                             endmat:=pvd^.data.PTD.GetValueAsString(pvd^.data.Instance);
1008                             if isfirst then
1009                                            begin
1010                                                 isfirst:=false;
1011                                                 nodestart:=nodeend;
1012                                                 startmat:=endmat;
1013                                                 startname:=endname;
1014                                            end;
1015                             if startmat<>endmat then
1016                             begin
1017                                  InsertDat(nodestart^.name,startname,prevname,count,currentcoord,drawings.GetCurrentDWG.ConstructObjRoot);
1018                                  count:=0;
1019                                  nodestart:=nodeend;
1020                                  startmat:=endmat;
1021                                  startname:=endname;
1022                                  //isfirst:=true;
1023                             end;
1024                             inc(count);
1025                         end;
1026                         prevname:=endname;
1027                         nodeend:=pcabledesk^.Devices.iterate(ir_inNodeArray);
1028                   until nodeend=nil;
1029                   if nodestart<>nil then
1030                                         InsertDat(nodestart^.name,startname,endname,count,currentcoord,drawings.GetCurrentDWG.ConstructObjRoot).YouDeleted(drawings.GetCurrentDWG^)
1031                                     else
1032                                         InsertDat('_error_here',startname,endname,count,currentcoord,drawings.GetCurrentDWG.ConstructObjRoot).YouDeleted(drawings.GetCurrentDWG^);
1033 
1034                   //pvd:=PTObjectUnit(PCableSS.ou.Instance)^.FindVariable('CABLE_WireCount');
1035                   pvd:=pCableSSvarext^.entityunit.FindVariable('CABLE_WireCount');
1036                   if pvd=nil then
1037                                  coord.x:=coord.x+12
1038                              else
1039                                  begin
1040                                       if pgdbinteger(pvd^.data.Instance)^<>0 then
1041                                                                                   coord.x:=coord.x+6*pgdbinteger(pvd^.data.Instance)^
1042                                                                               else
1043                                                                                   coord.x:=coord.x+12;
1044                                  end;
1045              end
1046 
1047         end;
1048 
1049 
1050   pcabledesk:=cman.iterate(ir);
1051   until pcabledesk=nil;
1052 
1053   cman.done;
1054 
1055   zcRedrawCurrentDrawing;
1056 end;
1057 procedure commformat2;
1058 var
1059    pcfd:PRecordDescriptor;
1060    pf:PfieldDescriptor;
1061 begin
1062    pcfd:=pointer(SysUnit.TypeName2PTD('TOrtoDevPlaceParam'));
1063    if pcfd<>nil then
1064 
1065      case OrtoDevPlaceParam.CountType of
1066           TODPCT_by_Count:begin
1067                                pf:=pcfd^.FindField('NX');
1068                                if pf<>nil then
1069                                               pf^.base.Attributes:=pf.base.Attributes or FA_READONLY;
1070 
1071                                pf:=pcfd^.FindField('NY');
1072                                if pf<>nil then
1073                                               pf^.base.Attributes:=pf.base.Attributes or FA_READONLY;
1074                                pf:=pcfd^.FindField('Count');
1075                                if pf<>nil then
1076                                               pf^.base.Attributes:=pf.base.Attributes and (not FA_READONLY);
1077                           end;
1078           TODPCT_by_XY:begin
1079                                pf:=pcfd^.FindField('NX');
1080                                if pf<>nil then
1081                                               pf^.base.Attributes:=pf.base.Attributes and (not FA_READONLY);
1082 
1083                                pf:=pcfd^.FindField('NY');
1084                                if pf<>nil then
1085                                               pf^.base.Attributes:=pf.base.Attributes and (not FA_READONLY);
1086                                pf:=pcfd^.FindField('Count');
1087                                if pf<>nil then
1088                                               pf^.base.Attributes:=pf.base.Attributes or FA_READONLY;
1089                        end;
1090      end;
1091 end;
PlCommandStartnull1092 function PlCommandStart(operands:pansichar):GDBInteger;
1093 var //i: GDBInteger;
1094     sd:TSelEntsDesk;
1095 begin
1096   OrtoDevPlaceParam.Name:='';
1097   sd:=zcGetSelEntsDeskInCurrentRoot;
1098     if sd.PFirstSelectedEnt<>nil then
1099     if (sd.PFirstSelectedEnt^.GetObjType=GDBBlockInsertID) then
1100     begin
1101          OrtoDevPlaceParam.Name:=PGDBObjBlockInsert(sd.PFirstSelectedEnt)^.name;
1102     end
1103 else if (sd.PFirstSelectedEnt^.GetObjType=GDBDeviceID) then
1104     begin
1105          OrtoDevPlaceParam.Name:=DevicePrefix+PGDBObjBlockInsert(sd.PFirstSelectedEnt)^.name;
1106     end;
1107 
1108   if (OrtoDevPlaceParam.Name='')or(sd.SelectedEntsCount=0)or(sd.SelectedEntsCount>1) then
1109                                    begin
1110                                         ZCMsgCallBackInterface.TextMessage('Должен быть выбран только один блок или устройство!',TMWOHistoryOut);
1111                                         commandmanager.executecommandend;
1112                                         exit;
1113                                    end;
1114 
1115   zcRedrawCurrentDrawing;
1116   result:=cmd_ok;
1117   drawings.GetCurrentDWG.wa.SetMouseMode((MGet3DPoint) or (MMoveCamera));
1118   ZCMsgCallBackInterface.TextMessage(rscmFirstCorner,TMWOHistoryOut);
1119   zcShowCommandParams(SysUnit.TypeName2PTD('CommandRTEdObject'),pco2);
1120   OPSPlaceSmokeDetectorOrtoParam.DMC:=TOPSMDC_1_2;
1121 end;
PlBeforeClicknull1122 function PlBeforeClick(wc: GDBvertex; mc: GDBvertex2DI; var button: GDBByte;osp:pos_record;mclick:GDBInteger): integer;
1123 begin
1124   result:=mclick;
1125   if (button and MZW_LBUTTON)<>0 then
1126     begin
1127       ZCMsgCallBackInterface.TextMessage('Второй угол',TMWOHistoryOut);
1128       t3dp:=wc;
1129     end
1130 end;
1131 procedure placedev(pva:PGDBObjEntityOpenArray;p1, p2: gdbvertex; nmax, nmin: GDBInteger; name: pansichar;a:gdbdouble;aa:gdbboolean;Norm:GDBBoolean);
1132 var dx, dy: GDBDouble;
1133   line1, line2: gdbline;
1134   l1, l2, i: integer;
1135   dir: gdbvertex;
1136 //  mincount:integer;
1137   sd,{dd,}sdd,{ddd,}angle:double;
1138   linelength:double;
1139 begin
1140   angle:=a;
1141   dx := p2.x - p1.x;
1142   dy := p2.y - p1.y;
1143   dx := abs(dx);
1144   dy := abs(dy);
1145   line1.lbegin := p1;
1146   line2.lbegin := p1;
1147   if dx < dy then
1148   begin
1149     line1.lend.x := p2.x;
1150     line1.lend.y := p1.y;
1151     line1.lend.z := 0;
1152     line2.lend.x := p1.x;
1153     line2.lend.y := p2.y;
1154     line2.lend.z := 0;
1155     sd:=dy/nmax/2;
1156     //dd:=dy/nmax;
1157     sdd:=dx/nmin/2;
1158     //ddd:=dx/nmin;
1159   end
1160   else
1161   begin
1162     line1.lend.x := p1.x;
1163     line1.lend.y := p2.y;
1164     line1.lend.z := 0;
1165     line2.lend.x := p2.x;
1166     line2.lend.y := p1.y;
1167     line2.lend.z := 0;
1168     sd:=dx/nmax/2;
1169     //dd:=dx/nmax;
1170     sdd:=dy/nmin/2;
1171     //ddd:=dy/nmin;
1172     if aa then
1173               angle:=angle+RightAngle;
1174 
1175   end;
1176   dir.x := line2.lend.x - line2.lbegin.x;
1177   dir.y := line2.lend.y - line2.lbegin.y;
1178   dir.z := line2.lend.z - line2.lbegin.z;
1179 
1180   l1:=nmin;
1181   l2:=nmax;
1182   Linelength:=Vertexlength(line1.lbegin, line1.lend);
1183   case l1 of
1184     1: begin
1185         place2(pva,Vertexmorph(line1.lbegin, line1.lend, 0.5), dir, l2, Linelength,sd,sd*2, name,angle,norm,OrtoDevPlaceParam.ScaleBlock,TPSS_Proportional);
1186        end;
1187     2: begin
1188         //if (Vertexlength(line1.lbegin, line1.lend) - 2 * sd)<dd then
1189         begin
1190         place2(pva,Vertexmorph(line1.lbegin, line1.lend, 1 / 4), dir, l2, Linelength,sd,sd*2, name,angle,norm,OrtoDevPlaceParam.ScaleBlock,TPSS_Proportional);
1191         place2(pva,Vertexmorph(line1.lbegin, line1.lend, 3 / 4), dir, l2, Linelength,sd,sd*2, name,angle,norm,OrtoDevPlaceParam.ScaleBlock,TPSS_Proportional);
1192         end
1193         {else
1194         begin
1195         place2(pva,Vertexmorphabs(line1.lbegin, line1.lend, sd), dir, l2, sd, name);
1196         place2(pva,Vertexmorphabs(line1.lbegin, line1.lend, -sd), dir, l2, sd, name);
1197         end}
1198        end
1199   else begin
1200       place2(pva,Vertexmorphabs2(line1.lbegin, line1.lend, sdd{}), dir, l2, Linelength,sd,sd*2, name,angle,norm,OrtoDevPlaceParam.ScaleBlock,TPSS_Proportional);
1201       place2(pva,Vertexmorphabs2(line1.lbegin, line1.lend, -sdd{}), dir, l2, Linelength,sd,sd*2, name,angle,norm,OrtoDevPlaceParam.ScaleBlock,TPSS_Proportional);
1202       line2.lbegin := Vertexmorphabs2(line1.lbegin, line1.lend, sdd);
1203       line2.lend := Vertexmorphabs2(line1.lbegin, line1.lend, -sdd);
1204       l1:=l1-2;
1205       for i := 1 to l1 do place2(pva,Vertexmorph(line2.lbegin, line2.lend, i / (l1 + 1)), dir, l2, Linelength,sd,sd*2, name,angle,norm,OrtoDevPlaceParam.ScaleBlock,TPSS_Proportional);
1206       //for i := 1 to l2 do place3(pva,Vertexmorph(line2.lbegin, line2.lend, i / (l2 )), dir, l1, dd, name);
1207        end
1208   end;
1209 end;
PlAfterClicknull1210 function PlAfterClick(wc: GDBvertex; mc: GDBvertex2DI; var button: GDBByte;osp:pos_record;mclick:GDBInteger): integer;
1211 var
1212 pl:pgdbobjline;
1213 //debug:string;
1214 //dw,dd:gdbdouble;
1215 nx,ny:GDBInteger;
1216 //t:GDBInteger;
1217 tt,tx,ty,ttx,tty:gdbdouble;
1218 DC:TDrawContext;
1219 begin
1220   //nx:=OrtoDevPlaceParam.NX;
1221   //ny:=OrtoDevPlaceParam.NY;
1222   result:=mclick;
1223   drawings.GetCurrentDWG.ConstructObjRoot.ObjArray.free;
1224 
1225 
1226   pl := PGDBObjLine(ENTF_CreateLine(@drawings.GetCurrentDWG.ConstructObjRoot,@drawings.GetCurrentDWG^.ConstructObjRoot.ObjArray,[t3dp.x,t3dp.y,t3dp.z,wc.x,wc.y,wc.z]));
1227   zcSetEntPropFromCurrentDrawingProp(pl);
1228   //pl := pointer(drawings.GetCurrentDWG.ConstructObjRoot.ObjArray.CreateObj(GDBLineID{,drawings.GetCurrentROOT}));
1229   //GDBObjLineInit(drawings.GetCurrentROOT,pl, drawings.GetCurrentDWG.LayerTable.GetCurrentLayer,sysvar.dwg.DWG_CLinew^, t3dp, wc);
1230   dc:=drawings.GetCurrentDWG^.CreateDrawingRC;
1231   pl^.FormatEntity(drawings.GetCurrentDWG^,dc);
1232 
1233      case OrtoDevPlaceParam.CountType of
1234           TODPCT_by_Count:begin
1235                                if abs(OrtoDevPlaceParam.Count)=1 then
1236                                           begin
1237                                                nx:=1;
1238                                                ny:=1;
1239                                           end
1240                           else
1241                               begin
1242                                    //t:=round(sqrt(abs(OrtoDevPlaceParam.Count)){+0.5});
1243                                    //tt:=abs(gdbobjline(pl^).CoordInOCS.lEnd.y-gdbobjline(pl^).CoordInOCS.lBegin.y)+abs(gdbobjline(pl^).CoordInOCS.lEnd.x-gdbobjline(pl^).CoordInOCS.lBegin.x);
1244                                    ty:=abs(gdbobjline(pl^).CoordInOCS.lEnd.y-gdbobjline(pl^).CoordInOCS.lBegin.y);
1245                                    tx:=abs(gdbobjline(pl^).CoordInOCS.lEnd.x-gdbobjline(pl^).CoordInOCS.lBegin.x);
1246 
1247                                    tt:=sqrt(tx*ty/OrtoDevPlaceParam.Count);
1248 
1249                                    {if tx>ty then
1250                                                 tx:=1/ty
1251                                             else
1252                                                 ty:=1/tx;}
1253 
1254                                    //tt:=gdbobjline(pl^).CoordInOCS.lEnd.y-gdbobjline(pl^).CoordInOCS.lBegin.y;
1255 
1256                                   { if abs(tt)>eps then
1257                                                       tt:=abs((gdbobjline(pl^).CoordInOCS.lEnd.x-gdbobjline(pl^).CoordInOCS.lBegin.x)/tt)
1258                                                   else
1259                                                       tt:=1000000000;
1260                                    if tt>1 then
1261                                               begin
1262                                                    //nx:=OrtoDevPlaceParam.count;
1263                                                    //ny:=1;
1264                                                    tt:=1/tt;
1265                                               end;
1266 
1267                                                begin
1268                                                    nx:=round(t*tx);
1269                                                    ny:=round(t*ty);
1270                                                end;}
1271                                    ttx:=(tx/tt);
1272                                    tty:=(ty/tt);
1273 
1274                       {             if ttx<0.5 then
1275                                                begin
1276                                                     nx:=1;
1277                                                     ny:=OrtoDevPlaceParam.Count;
1278                                                end
1279                               else if tty<0.5 then
1280                                                begin
1281                                                     ny:=1;
1282                                                     nx:=OrtoDevPlaceParam.Count;
1283                                                end
1284                               else
1285                                   begin
1286                                    nx:=round(tx/tt);
1287                                    ny:=round(ty/tt);
1288                                   end;
1289 
1290                                    while nx*ny<OrtoDevPlaceParam.Count do
1291                                    if tx<ty then
1292                                                 inc(ny)
1293                                             else
1294                                                 inc(nx)}
1295                                    if ttx<tty then
1296                                                   begin
1297                                                        //tt:=tx;
1298                                                        //tx:=ty;
1299                                                        //ty:=tt;
1300 
1301                                                        tt:=ttx;
1302                                                        //ttx:=tty;
1303                                                        tty:=tt;
1304 
1305                                                   end;
1306                                    ny:=round(tty);
1307                                    if ny=0 then
1308                                                ny:=1;
1309                                    if ny>OrtoDevPlaceParam.Count then
1310                                                ny:=OrtoDevPlaceParam.Count;
1311                                    nx:=ceil(OrtoDevPlaceParam.Count/ny);
1312                               end;
1313                           end;
1314           TODPCT_by_XY:begin
1315                             nx:=OrtoDevPlaceParam.NX;
1316                             ny:=OrtoDevPlaceParam.NY;
1317                        end;
1318      end;
1319   if button=0 then
1320   begin
1321        placedev(@drawings.GetCurrentDWG.ConstructObjRoot.ObjArray,gdbobjline(pl^).CoordInWCS.lbegin, gdbobjline(pl^).CoordInWCS.lend, NX, NY,@OrtoDevPlaceParam.Name[1],OrtoDevPlaceParam.Angle,OrtoDevPlaceParam.AutoAngle,OrtoDevPlaceParam.NormalizePoint);
1322   end
1323   else
1324   begin
1325        result:=-1;
1326        pco^.mouseclic:=-1;
1327        //drawings.GetCurrentDWG.ConstructObjRoot.cleareraseobj;
1328        placedev(@drawings.GetCurrentROOT.ObjArray,gdbobjline(pl^).CoordInWCS.lbegin, gdbobjline(pl^).CoordInWCS.lend, NX, NY,@OrtoDevPlaceParam.Name[1],OrtoDevPlaceParam.Angle,OrtoDevPlaceParam.AutoAngle,OrtoDevPlaceParam.NormalizePoint);
1329        drawings.GetCurrentDWG.ConstructObjRoot.ObjArray.free;
1330 
1331        drawings.GetCurrentROOT.calcbb(dc);
1332        zcRedrawCurrentDrawing;
1333        ZCMsgCallBackInterface.TextMessage(rscmFirstCorner,TMWOHistoryOut);
1334        //commandend;
1335        //pcommandmanager^.executecommandend;
1336   end;
1337 //  if button = 1 then
1338 //  begin
1339 //    pgdbinplugin^.ObjArray.add(addr(pc));
1340 //    pgdbinplugin^.ConstructObjRoot.Count := 0;
1341 //    commandend;
1342 //    executecommandend;
1343 //  end;
1344 end;
1345 procedure startup;
1346 begin
1347   OPS_SPBuild_com.init('OPS_SPBuild',0,0);
1348   //CreateCommandFastObjectPlugin(@OPS_SPBuild_com,'OPS_SPBuild',CADWG,0);
1349 
1350   CreateCommandFastObjectPlugin(@OPS_Sensor_Mark_com,'OPS_Sensor_Mark',CADWG,0);
1351   pco:=CreateCommandRTEdObjectPlugin(@CommandStart,nil,nil,@commformat,@BeforeClick,@AfterClick,nil,nil,'PlaceSmokeDetectorOrto',0,0);
1352   pco^.SetCommandParam(@OPSPlaceSmokeDetectorOrtoParam,'PTOPSPlaceSmokeDetectorOrtoParam');
1353   OPSPlaceSmokeDetectorOrtoParam.InsertType:=TIT_Device;
1354   OPSPlaceSmokeDetectorOrtoParam.Height.Enums.init(10);
1355   OPSPlaceSmokeDetectorOrtoParam.DatType:=TOPSDT_Smoke;
1356   OPSPlaceSmokeDetectorOrtoParam.StartAuto:=false;
1357   OPSPlaceSmokeDetectorOrtoParam.DMC:=TOPSMDC_2;
1358   OPSPlaceSmokeDetectorOrtoParam.Scale:=100;
1359   OPSPlaceSmokeDetectorOrtoParam.ScaleBlock:=1;
1360   OPSPlaceSmokeDetectorOrtoParam.oldth:=0;
1361   OPSPlaceSmokeDetectorOrtoParam.oldsh:=0;
1362   OPSPlaceSmokeDetectorOrtoParam.olddt:=TOPSDT_Termo;
1363   OPSPlaceSmokeDetectorOrtoParam.NormalizePoint:=True;
1364   OPSPlaceSmokeDetectorOrtoParam.PlaceStrategy:=TPSS_Proportional;
1365   OPSPlaceSmokeDetectorOrtoParam.ReductionFactor:=1;
1366   OPSPlaceSmokeDetectorOrtoParam.SensorSensorDistance:=TARDM_LongAxis;
1367   OPSPlaceSmokeDetectorOrtoParam.SensorWallDistance:=TARDM_Nothing;
1368   commformat;
1369 
1370   pco2:=CreateCommandRTEdObjectPlugin(@PlCommandStart,nil,nil,@commformat2,@PlBeforeClick,@PlAfterClick,nil,nil,'OrtoDevPlace',0,0);
1371 
1372   pco2^.SetCommandParam(@OrtoDevPlaceParam,'PTOrtoDevPlaceParam');
1373 
1374   OrtoDevPlaceParam.ScaleBlock:=1;
1375   OrtoDevPlaceParam.NX:=2;
1376   OrtoDevPlaceParam.NY:=2;
1377   OrtoDevPlaceParam.Count:=2;
1378   OrtoDevPlaceParam.Angle:=0;
1379   OrtoDevPlaceParam.AutoAngle:=false;
1380   OrtoDevPlaceParam.NormalizePoint:=true;
1381   commformat2;
1382   //format;
1383 end;
1384 procedure finalize;
1385 begin
1386   OPSPlaceSmokeDetectorOrtoParam.Height.Enums.Done;
1387   //result := 0;
1388 end;
1389 initialization
1390   startup;
1391 finalization
1392   debugln('{I}[UnitsFinalization] Unit "',{$INCLUDE %FILE%},'" finalization');
1393   finalize;
1394 end.
1395