diff --git a/POWERCAD30/UNITS/form3d.dfm b/POWERCAD30/UNITS/form3d.dfm index 2e1f4c1..38981b5 100644 --- a/POWERCAD30/UNITS/form3d.dfm +++ b/POWERCAD30/UNITS/form3d.dfm @@ -3405,7 +3405,7 @@ object frm3D: Tfrm3D Left = 100 Top = 57 Bitmap = { - 494C01013A00B0006C0210001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 494C01013A00B000940210001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 000000000000360000002800000040000000F0000000010020000000000000F0 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 diff --git a/POWERCAD30/UNITS/form3d.pas b/POWERCAD30/UNITS/form3d.pas index 9197767..08872d9 100644 --- a/POWERCAD30/UNITS/form3d.pas +++ b/POWERCAD30/UNITS/form3d.pas @@ -464,6 +464,11 @@ type procedure trWallTransparencyChange(Sender: TObject); procedure tbSetWallsTransparencyClick(Sender: TObject); private + //Tolik 27/05/25 -- + { Private declarations } + Arrows: array[0..5] of TGLArrowLine; + Labels: array[0..5] of TGLHUDText; + // { Private declarations } //Tolik 17/12/2018 -- //procedure Rotate3DSObj(aObject: TGLFreeForm; aX, aY, aZ: Double); @@ -1509,6 +1514,7 @@ begin end; // Move Line Object if (Obj <> nil) and (Obj is TGLLines) then + {$IF Defined(ES_GRAPH_SC)} if FSelection.Count <= 3 then if isLineObject(TGLBaseSceneObject(FSelection[GetCornerIndex(FSelection)]), Obj) then @@ -3386,8 +3392,314 @@ var HalfWidth, WireStep: Double; WireNode: TTreeNode; GLTray: TGLFreeForm; + cp1, cp2, cp3,cp4, cp5, cp6: TDoublepoint; + //Tolik 13/05/2025 -- + Procedure CheckInterSection(aSide: integer); + var i: integer; + LineList: TList; + AngleArray: array of double; + LineConn: TConnectorObject; + currLine: TOrthoLine; + LineCatalog: TSCSCatalog; + LineAngle: Double; + canExchange: Boolean; + Point1, Point2: TDoublePoint; + LeftLine, RightLine: TOrthoLine; + LeftWireTray, RightWireTray: TSCSComponent; + SCSCatalog: TSCSCatalog; + CrossWarewidth: Double; + crPoint1, crPoint2: TDoublePoint; + Procedure SetCrossPoint(acrossSide: integer); //Tolik 15/05/2025 -- расчет точки пересечения + var A1, B1, C1, A2, B2, C2: Double; + Denominator, X, Y: Double; + begin + // Вычисляем коэффициенты для первой прямой (A1x + B1y + C1 = 0) + if aSide = 1 then + begin + if (acrossSide = 1) then //(левое пересечение) + begin + A1 := cp3.Y - cp4.Y; + B1 := cp4.X - cp3.X; + C1 := -A1 * cp4.X - B1 * cp4.Y; + end; + if (acrossSide = 2) then //(правое пересечение) + begin + A1 := cp1.Y - cp6.Y; + B1 := cp6.X - cp1.X; + C1 := -A1 * cp6.X - B1 * cp6.Y; + end; + end; + if aSide = 2 then + begin + // Вычисляем коэффициенты для первой прямой (A1x + B1y + C1 = 0) + if (acrossSide = 1) then //(левое пересечение) + begin + A1 := cp6.Y - cp1.Y; + B1 := cp1.X - cp6.X; + C1 := -A1 * cp1.X - B1 * cp1.Y; + end; + if (acrossSide = 2) then //(правое пересечение) + begin + A1 := cp4.Y - cp3.Y; + B1 := cp3.X - cp4.X; + C1 := -A1 * cp3.X - B1 * cp3.Y; + end; + end; + + // Вычисляем коэффициенты для второй прямой (A2x + B2y + C2 = 0) + A2 := ap1.Y - ap4.Y; + B2 := ap4.X - ap1.X; + C2 := -A2 * ap4.X - B2 * ap4.Y; + + // Вычисляем знаменатель + Denominator := A1 * B2 - A2 * B1; + //если не на одной прямой + if CompareValue(ABS(Denominator), 0.01) <> -1 then + begin + // Находим точку пересечения + if aSide = 1 then + begin + if aCrossSide = 1 then + begin + cp3.X := (B1 * C2 - B2 * C1) / Denominator; + cp3.Y := (A2 * C1 - A1 * C2) / Denominator; + end + else + if aCrossSide = 2 then + begin + cp1.X := (B1 * C2 - B2 * C1) / Denominator; + cp1.Y := (A2 * C1 - A1 * C2) / Denominator; + end; + end + else + if aSide = 2 then + begin + if aCrossSide = 1 then + begin + cp6.X := (B1 * C2 - B2 * C1) / Denominator; + cp6.Y := (A2 * C1 - A1 * C2) / Denominator; + end + else + if aCrossSide = 2 then + begin + cp4.X := (B1 * C2 - B2 * C1) / Denominator; + cp4.Y := (A2 * C1 - A1 * C2) / Denominator; + end; + end; + end; + end; + begin + SetLength(AngleArray, 0); + LeftWireTray := nil; + RightWireTray := nil; + if aSide = 1 then + LineConn := TConnectorObject(aLine.JoinConnector1) + else + LineConn := TConnectorObject(aLine.JoinConnector2); + + LineList := TList.Create; + + if LineConn.JoinedConnectorsList.Count = 0 then + begin + //список трасс на коннекторе + for i := 0 to LineConn.JoinedOrtholinesList.Count - 1 do + begin + currLine := TOrthoLine(LineConn.JoinedOrtholinesList[i]); + LineList.Add(currLine); + end; + + //если других трасс нет - перерасчет точек не нужен + if LineList.Count = 1 then + begin + + end + else + //если две, то соседние искать не нужно + if LineList.Count = 2 then + begin + LeftLine := nil; + RightLine := nil; + if TOrthoLine(LineList[0]).ID = aLine.ID then + LeftLine := TOrthoLine(LineList[1]) + else + LeftLine := TOrthoLine(LineList[0]); + + SCSCatalog := F_ProjMan.GSCSBase.CurrProject.GetCatalogFromReferencesBySCSID(LeftLine.ID); + if SCSCatalog <> nil then + begin + for i := 0 to SCSCatalog.ComponentReferences.Count - 1 do + begin + if SCSCatalog.ComponentReferences[i].ComponentType.SysName = ctsnWireTray then + begin + LeftWireTray := SCSCatalog.ComponentReferences[i]; + break; + end; + end; + end; + + if LeftWireTray <> nil then + begin + RightWireTray := LeftWireTray; + RightLine := LeftLine; + end; + end + else //здесь 3 и более (для каждой нужно искать соседнюю левую и соседнюю правую) + begin + setLength(angleArray, LineList.Count); // углы наклона трасс + for i := 0 to LineList.Count - 1 do + begin + currLine := TOrthoLine(LineList[i]); + if currLine.JoinConnector1.ID = LineConn.ID then + LineAngle := currLine.GetAngleDF(TConnectorObject(currLine.JoinConnector1).ap1.x, TConnectorObject(currLine.JoinConnector1).ap1.y, + TConnectorObject(currLine.JoinConnector2).ap1.x, TConnectorObject(currLine.JoinConnector2).ap1.y) + else + LineAngle := currLine.GetAngleDF(TConnectorObject(currLine.JoinConnector2).ap1.x, TConnectorObject(currLine.JoinConnector2).ap1.y, + TConnectorObject(currLine.JoinConnector1).ap1.x, TConnectorObject(currLine.JoinConnector1).ap1.y); + angleArray[i] := LineAngle; + end; + //сортировка + CanExchange := True; + while CanExchange do + begin + CanExchange := False; + for i := 0 to LineList.Count - 2 do + begin + LineAngle := angleArray[i]; + if CompareValue(LineAngle, angleArray[i + 1]) = 1 then + begin + CanExchange := true; + LineList.Exchange(i, i+1); + angleArray[i] := angleArray[i + 1]; + angleArray[i + 1] := LineAngle; + break; + end; + end; + end; + //здесь берем две соседние трассы с текущей из списка + for i := 0 to LineList.Count - 1 do + begin + if TOrthoLine(LineList[i]).ID = aLine.ID then + begin + if i = 0 then + begin + LeftLine := TOrthoLine(LineList[i + 1]); + RightLine := TOrthoLine(LineList[LineList.Count - 1]); + end + else + if i = (LineList.Count - 1) then + begin + LeftLine := TOrthoLine(LineList[0]); + RightLine := TOrthoLine(LineList[i - 1]); + end + else + begin + LeftLine := TOrthoLine(LineList[i + 1]); + RightLine := TOrthoLine(LineList[i - 1]); + end; + break; + end; + end; + //ищем лотки справа и слева + LeftWireTray := nil; + RightWireTray := nil; + + SCSCatalog := F_ProjMan.GSCSBase.CurrProject.GetCatalogFromReferencesBySCSID(LeftLine.ID); + if SCSCatalog <> nil then + begin + for i := 0 to SCSCatalog.ComponentReferences.Count - 1 do + begin + if SCSCatalog.ComponentReferences[i].ComponentType.SysName = ctsnWireTray then + begin + LeftWireTray := SCSCatalog.ComponentReferences[i]; + break; + end; + end; + end; + + SCSCatalog := F_ProjMan.GSCSBase.CurrProject.GetCatalogFromReferencesBySCSID(RightLine.ID); + if SCSCatalog <> nil then + begin + for i := 0 to SCSCatalog.ComponentReferences.Count - 1 do + begin + if SCSCatalog.ComponentReferences[i].ComponentType.SysName = ctsnWireTray then + begin + RightWireTray := SCSCatalog.ComponentReferences[i]; + break; + end; + end; + end; + end; + //Tolik 15/05/2025 -- левый лоток(если задана ширина) + if LeftWireTray <> nil then + begin + WireTrayWidth := 0; + LineComponProp := LeftWireTray.GetPropertyBySysName(pnWidth); + if LineComponProp <> nil then + WireTrayWidth := LeftWireTray.GetPropertyValueAsFloat(pnWidth); + if WireTrayWidth <> 0 then + begin + HalfWidth := WireTrayWidth/2; + + p1 := GetPoint(LeftLine, 1, HalfWidth); + p2 := GetPoint(LeftLine, 2, HalfWidth); + //если пересечение на коннекторе1 + if LineConn.ID = LeftLine.JoinConnector1.ID then + begin + ap1 := RotatePoint(LeftLine.ap1, p1^, -PI/2); + ap4 := RotatePoint(LeftLine.ap2, p2^, PI/2); + end + else + begin // на втором коннекторе + ap1 := RotatePoint(LeftLine.ap2, p2^, -PI/2); + ap4 := RotatePoint(LeftLine.ap1, p1^, PI/2); + end; + SetCrossPoint(1); + end; + end; + //Tolik 15/05/2025 -- левый лоток(если задана ширина) + if RightWireTray <> nil then + begin + WireTrayWidth := 0; + LineComponProp := RightWireTray.GetPropertyBySysName(pnWidth); + if LineComponProp <> nil then + WireTrayWidth := RightWireTray.GetPropertyValueAsFloat(pnWidth); + if WireTrayWidth <> 0 then + begin + HalfWidth := WireTrayWidth/2; + + p1 := GetPoint(RightLine, 1, HalfWidth); + p2 := GetPoint(RightLine, 2, HalfWidth); + + //если приходит на первый коннектор: + if LineConn.ID = RightLine.JoinConnector1.ID then + begin + ap1 := RotatePoint(RightLine.ap1, p1^, PI/2); + ap4 := RotatePoint(RightLine.ap2, p2^, -PI/2); + end + else + begin + ap1 := RotatePoint(RightLine.ap2, p2^, PI/2); + ap4 := RotatePoint(RightLine.ap1, p1^, -PI/2); + end; + + //контур поддона лотка Tolik 15/05/2025 -- + { + ap1 := RotatePoint(aLine.ap1, p1^, -PI/2); + ap2 := RotatePoint(aLine.ap1, p1^, PI/2); + ap3 := RotatePoint(aLine.ap2, p2^, -PI/2); + ap4 := RotatePoint(aLine.ap2, p2^, PI/2); + } + SetCrossPoint(2); + end; + end; + end; + + LineList.Free; + SetLength(angleArray, 0); + end; + // begin if LineLen = 0 then exit; @@ -3463,54 +3775,8 @@ var Arg_um_ent := ((pp1.y - pp2.y) / cubeLineLen); LinearAngle1 := RadToDeg(ArcSin(Arg_um_ent)); - //LinearAngle1 := ArcSin((pp1.y - pp2.y) / cubeLineLen); - //LinearAngle1 := RadToDeg(LinearAngle1); - - LinearAngle := aLine.GetAngleDF(pp1.x, pp1.z, pp2.x, pp2.z); - // LinearAngle1 := RadToDeg(ArcSin((TubePoint1.z - TubePoint2.z) / cubeLineLen)); - // LinearAngle := aLine.GetAngleDF(TubePoint1.x, TubePoint1.y, TubePoint2.x, TubePoint2.y); - - {While LinearAngle > 180 do - LinearAngle := LinearAngle - 180; - - if LinearAngle <> 0 then - begin - // glComponCube.RotateAbsolute(0, 180 - LinearAngle, 0); - //glComponCube.RotateAbsolute(0,180 - LinearAngle - 1, 0); - end; - // по Z - if (CompareValue(TubePoint1.z, TubePoint2.z) <> 0) then - begin - if ((CompareValue(TubePoint1.x, TubePoint2.x) = 0) and (CompareValue(TubePoint1.y, TubePoint2.y) = 0)) then - begin - glComponCube.RotateAbsolute(0, 0, 90); - end - else - begin - gp := SQRT(SQR(Face.Points[0].x - Face.Points[1].x) + SQR(Face.Points[0].y - Face.Points[1].y) + SQR(Face.Points[0].z - Face.Points[1].z)); - ct := (ABS(Face.Points[0].z - Face.Points[1].z)); - LinearAngle1 := RadToDeg(ArcSin(ct/ gp)); - - if CompareValue(Face.Points[0].z, Face.Points[1].z) <> 0 then - begin - if CompareValue(Face.Points[0].z, Face.Points[1].z) = -1 then - begin - dist1 := SQRT(Sqr(Face.Points[0].x) + Sqr(Face.Points[0].y) + Sqr(Face.Points[0].z)); - dist2 := SQRT(Sqr(Face.Points[1].x) + Sqr(Face.Points[1].y) + Sqr(Face.Points[1].z)); - end - else - begin - dist2 := SQRT(Sqr(Face.Points[0].x) + Sqr(Face.Points[0].y) + Sqr(Face.Points[0].z)); - dist1 := SQRT(Sqr(Face.Points[1].x) + Sqr(Face.Points[1].y) + Sqr(Face.Points[1].z)); - end; - if CompareValue(dist1, dist2) = -1 then - LinearAngle1 := 180 - LinearAngle1; - end; - end; - end;} - if cubeLineLen > 0 then begin glComponCube := TGLCube(DummyCube.AddNewChild(TglCube)); @@ -3641,7 +3907,10 @@ var end; GLCyl.Material.MaterialOptions := []; - GLCyl.Material.Texture.Disabled := False; + //Tolik 30/05/2025 -- + //GLCyl.Material.Texture.Disabled := False; + GLCyl.Material.Texture.Disabled := True; + // GLCyl.TagObject := ChildNode; F3DLineCompon.FGLObject := GLCyl; @@ -3656,7 +3925,6 @@ var //Tolik 10/04/2025 -- if aCompon.ComponentType.SysName = ctsnWireTray then // Проволочный лоток begin - CheckInterSection; //Tolik 13/05/2025 -- WireTrayWidth := 0; WireTrayHeight := 0; SetLength(ap, 0); @@ -3675,12 +3943,26 @@ var p1 := GetPoint(aLine, 1, HalfWidth); p2 := GetPoint(aLine, 2, HalfWidth); - + //контур поддона лотка Tolik 15/05/2025 -- + cp1 := RotatePoint(aLine.ap1, p1^, -PI/2); + cp1.z := p1.z; + cp2 := aLine.ap1; + cp2.z := p1.z; + cp3 := RotatePoint(aLine.ap1, p1^, PI/2); + cp3.z := p1.z; + cp4 := RotatePoint(aLine.ap2, p2^, -PI/2); + cp4.z := p2.z; + cp5 := aLine.ap2; + cp5.z := p2.z; + cp6 := RotatePoint(aLine.ap2, p2^, PI/2); + cp6.z := p2.z; + { ap1 := RotatePoint(aLine.ap1, p1^, -PI/2); ap2 := RotatePoint(aLine.ap1, p1^, PI/2); ap3 := RotatePoint(aLine.ap2, p2^, -PI/2); ap4 := RotatePoint(aLine.ap2, p2^, PI/2); + } F3DLineCompon := T3DLineComponent.Create(nil, nil,Self.F3DModel); Self.F3DModel.FScsObjects.Add(F3DLineCompon); @@ -3690,115 +3972,120 @@ var ChildNode.Data := F3DLineCompon; F3DLineCompon.FSCSCompon := aCompon; F3DLineCompon.FSCSComponID := aCompon.ID; - (* - GLTray := TGLFREEFORM(DummyCube.AddNewChild(TGLLines)); - //дно лотка с шагом в 10 см - TglLines(GLTray).Nodes.AddNode(ap1.x * factor, ap1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap1.y * factor); - TglLines(GLTray).Nodes.AddNode(ap2.x * factor, ap2.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap2.y * factor); - TglLines(GLTray).Nodes.AddNode(ap2.x * factor, ap2.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap2.y * factor); - TglLines(GLTray).Nodes.AddNode(ap3.x * factor, ap3.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap3.y * factor); - TglLines(GLTray).Nodes.AddNode(ap3.x * factor, ap3.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap3.y * factor); - TglLines(GLTray).Nodes.AddNode(ap4.x * factor, ap4.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap4.y * factor); - TglLines(GLTray).Nodes.AddNode(ap4.x * factor, ap4.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap4.y * factor); - TglLines(GLTray).Nodes.AddNode(ap1.x * factor, ap1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap1.y * factor); - - Dispose(p1); - Dispose(p2); - - while comparevalue(HalfWidth, 0.1) = 1 do - begin - HalfWidth := HalfWidth - 0.1; - p1 := GetPoint(aLine, 1, HalfWidth); - p2 := GetPoint(aLine, 2, HalfWidth); - - ap5 := RotatePoint(aLine.ap1, p1^, -PI/2); - ap6 := RotatePoint(aLine.ap1, p1^, PI/2); - ap7 := RotatePoint(aLine.ap2, p2^, -PI/2); - ap8 := RotatePoint(aLine.ap2, p2^, PI/2); - - TglLines(GLTray).Nodes.AddNode(ap6.x * factor, ap6.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap6.y * factor); - TglLines(GLTray).Nodes.AddNode(ap7.x * factor, ap7.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap7.y * factor); - TglLines(GLTray).Nodes.AddNode(ap8.x * factor, ap8.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap8.y * factor); - TglLines(GLTray).Nodes.AddNode(ap5.x * factor, ap5.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap5.y * factor); - - Dispose(p1); - Dispose(p2); - end; - - - if WireTrayHeight > 0 then //если задана высота, рисуем боковушки - begin - HalfWidth := WireTrayHeight; - - TglLines(GLTray).Nodes.AddNode(ap1.x * factor, (ap1.z + HalfWidth)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap1.y * factor); - TglLines(GLTray).Nodes.AddNode(ap1.x * factor, ap1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap1.y * factor); - TglLines(GLTray).Nodes.AddNode(ap1.x * factor, ap1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap1.y * factor); - TglLines(GLTray).Nodes.AddNode(ap4.x * factor, ap4.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap4.y * factor); - TglLines(GLTray).Nodes.AddNode(ap4.x * factor, ap4.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap4.y * factor); - TglLines(GLTray).Nodes.AddNode(ap4.x * factor, (ap4.z + HalfWidth)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap4.y * factor); - TglLines(GLTray).Nodes.AddNode(ap4.x * factor, (ap4.z + HalfWidth)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap4.y * factor); - TglLines(GLTray).Nodes.AddNode(ap1.x * factor, (ap1.z + HalfWidth)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap1.y * factor); - - while comparevalue(HalfWidth, 0.1) = 1 do - begin - HalfWidth := HalfWidth - 0.1; - TglLines(GLTray).Nodes.AddNode(ap1.x * factor, (ap1.z + HalfWidth)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap1.y * factor); - //TglLines(GLTray).Nodes.AddNode(ap1.x * factor, ap1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap1.y * factor); - TglLines(GLTray).Nodes.AddNode(ap4.x * factor, ap4.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap4.y * factor); - TglLines(GLTray).Nodes.AddNode(ap4.x * factor, (ap4.z + HalfWidth)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap4.y * factor); - TglLines(GLTray).Nodes.AddNode(ap1.x * factor, (ap1.z + HalfWidth)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap1.y * factor); - end; - - //вторая - HalfWidth := WireTrayHeight; - - TglLines(GLTray).Nodes.AddNode(ap2.x * factor, (ap2.z + HalfWidth)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap2.y * factor); - TglLines(GLTray).Nodes.AddNode(ap2.x * factor, ap2.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap2.y * factor); - TglLines(GLTray).Nodes.AddNode(ap2.x * factor, ap2.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap2.y * factor); - TglLines(GLTray).Nodes.AddNode(ap3.x * factor, ap3.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap3.y * factor); - TglLines(GLTray).Nodes.AddNode(ap3.x * factor, ap3.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap3.y * factor); - TglLines(GLTray).Nodes.AddNode(ap3.x * factor, (ap3.z + HalfWidth)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap3.y * factor); - TglLines(GLTray).Nodes.AddNode(ap3.x * factor, (ap3.z + HalfWidth)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap3.y * factor); - TglLines(GLTray).Nodes.AddNode(ap2.x * factor, (ap2.z + HalfWidth)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap2.y * factor); - - while comparevalue(HalfWidth, 0.1) = 1 do - begin - HalfWidth := HalfWidth - 0.1; - //TglLines(GLTray).Nodes.AddNode(ap2.x * factor, (ap2.z + HalfWidth)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap2.y * factor); - TglLines(GLTray).Nodes.AddNode(ap2.x * factor, ap2.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap2.y * factor); - TglLines(GLTray).Nodes.AddNode(ap3.x * factor, ap3.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap3.y * factor); - TglLines(GLTray).Nodes.AddNode(ap3.x * factor, (ap3.z + HalfWidth)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap3.y * factor); - TglLines(GLTray).Nodes.AddNode(ap2.x * factor, (ap2.z + HalfWidth)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap2.y * factor); - end; - end; - - //TglLines(GLTray).SplineMode := lsmSegments; - - if GLTray.Material.Texture.Disabled then - begin - ComponColor := getLineComponColor(aCompon);//ConvertWinColor(clGreen); - GLTray.Material.FrontProperties.Ambient.Color := ComponColor; - GLTray.Material.FrontProperties.Diffuse.Color := ComponColor; - GLTray.Material.FrontProperties.Emission.Color := ComponColor; - GLTray.Material.BackProperties.Ambient.Color := ComponColor; - GLTray.Material.BackProperties.Diffuse.Color := ComponColor; - GLTray.Material.BackProperties.Emission.Color := ComponColor; - end; - - GLTray.Material.MaterialOptions := []; - GLTray.Material.Texture.Disabled := False; - GLTray.TagObject := ChildNode; - F3DLineCompon.FGLObject := GLTray; - TglLines(GLTray).ShowAxes := False; - TglLines(GLTray).LineColor.AsWinColor := clgreen;//TGLColor(ComponColor); - TglLines(GLTray).LineWidth := 4; - TglLines(GLTray).NodeSize := 0; - TglLines(GLTray).NodesAspect := lnaInvisible; - TglLines(GLTray).AntiAliased := true; - *) GLPipe := TGLFREEFORM(DummyCube.AddNewChild(TGLPipe)); TGLPipe(GLPipe).Radius := 0.01 * UOMToMetre(1000 / FCAD.PCad.MapScale) * factor; + + if GLPipe.Material.Texture.Disabled then + begin + ComponColor := getLineComponColor(aCompon);//ConvertWinColor(clGreen); + GLPipe.Material.FrontProperties.Ambient.Color := ComponColor; + GLPipe.Material.FrontProperties.Diffuse.Color := ComponColor; + GLPipe.Material.FrontProperties.Emission.Color := ComponColor; + GLPipe.Material.BackProperties.Ambient.Color := ComponColor; + GLPipe.Material.BackProperties.Diffuse.Color := ComponColor; + GLPipe.Material.BackProperties.Emission.Color := ComponColor; + end; + + GLPipe.Material.MaterialOptions := []; + //GLPipe.Material.Texture.Disabled := False; + GLPipe.Material.Texture.Disabled := true; + GLPipe.TagObject := ChildNode; + F3DLineCompon.FGLObject := GLPipe; + TGLPipe(GLPipe).ObjectStyle := TGLPipe(GLPipe).ObjectStyle + [osDirectDraw]; + TGLPipe(GLPipe).SplineMode := lsmSegments;//lsmLines; // + + CheckInterSection(1); //Tolik 13/05/2025 -- + CheckInterSection(2); + + TGLPipe(GLPipe).Nodes.AddNode(cp1.x * factor, cp1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp1.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp2.x * factor, cp2.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp2.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp3.x * factor, cp3.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp3.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp4.x * factor, cp4.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp4.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp5.x * factor, cp5.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp5.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp6.x * factor, cp6.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp6.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp1.x * factor, cp1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp1.y * factor); + + //боковушки + if WireTrayHeight <> 0 then + begin + //правая + F3DLineCompon := T3DLineComponent.Create(nil, nil,Self.F3DModel); + Self.F3DModel.FScsObjects.Add(F3DLineCompon); + childNode := DuplicateNodeTree.Items.AddChild(nil, aCompon.GetNameForVisible); + childNode.ImageIndex := 8; + childNode.SelectedIndex := 2; + ChildNode.Data := F3DLineCompon; + F3DLineCompon.FSCSCompon := aCompon; + F3DLineCompon.FSCSComponID := aCompon.ID; + + GLPipe := TGLFREEFORM(DummyCube.AddNewChild(TGLPipe)); + TGLPipe(GLPipe).Radius := 0.01 * UOMToMetre(1000 / FCAD.PCad.MapScale) * factor; + + if GLPipe.Material.Texture.Disabled then + begin + ComponColor := getLineComponColor(aCompon);//ConvertWinColor(clGreen); + GLPipe.Material.FrontProperties.Ambient.Color := ComponColor; + GLPipe.Material.FrontProperties.Diffuse.Color := ComponColor; + GLPipe.Material.FrontProperties.Emission.Color := ComponColor; + GLPipe.Material.BackProperties.Ambient.Color := ComponColor; + GLPipe.Material.BackProperties.Diffuse.Color := ComponColor; + GLPipe.Material.BackProperties.Emission.Color := ComponColor; + end; + + GLPipe.Material.MaterialOptions := []; + //GLPipe.Material.Texture.Disabled := False; + GLPipe.Material.Texture.Disabled := true; + GLPipe.TagObject := ChildNode; + F3DLineCompon.FGLObject := GLPipe; + TGLPipe(GLPipe).ObjectStyle := TGLPipe(GLPipe).ObjectStyle + [osDirectDraw]; + TGLPipe(GLPipe).SplineMode := lsmSegments;//lsmLines; // + + TGLPipe(GLPipe).Nodes.AddNode(cp1.x * factor, cp1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp1.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp6.x * factor, cp6.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp6.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp6.x * factor, (cp6.z + WireTrayHeight)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp6.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp1.x * factor, (cp1.z + WireTrayHeight)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp1.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp1.x * factor, cp1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp1.y * factor); + //Левая + F3DLineCompon := T3DLineComponent.Create(nil, nil,Self.F3DModel); + Self.F3DModel.FScsObjects.Add(F3DLineCompon); + childNode := DuplicateNodeTree.Items.AddChild(nil, aCompon.GetNameForVisible); + childNode.ImageIndex := 8; + childNode.SelectedIndex := 2; + ChildNode.Data := F3DLineCompon; + F3DLineCompon.FSCSCompon := aCompon; + F3DLineCompon.FSCSComponID := aCompon.ID; + + GLPipe := TGLFREEFORM(DummyCube.AddNewChild(TGLPipe)); + TGLPipe(GLPipe).Radius := 0.01 * UOMToMetre(1000 / FCAD.PCad.MapScale) * factor; + + if GLPipe.Material.Texture.Disabled then + begin + ComponColor := getLineComponColor(aCompon);//ConvertWinColor(clGreen); + GLPipe.Material.FrontProperties.Ambient.Color := ComponColor; + GLPipe.Material.FrontProperties.Diffuse.Color := ComponColor; + GLPipe.Material.FrontProperties.Emission.Color := ComponColor; + GLPipe.Material.BackProperties.Ambient.Color := ComponColor; + GLPipe.Material.BackProperties.Diffuse.Color := ComponColor; + GLPipe.Material.BackProperties.Emission.Color := ComponColor; + end; + + GLPipe.Material.MaterialOptions := []; + //GLPipe.Material.Texture.Disabled := False; + GLPipe.Material.Texture.Disabled := true; + GLPipe.TagObject := ChildNode; + F3DLineCompon.FGLObject := GLPipe; + TGLPipe(GLPipe).ObjectStyle := TGLPipe(GLPipe).ObjectStyle + [osDirectDraw]; + TGLPipe(GLPipe).SplineMode := lsmSegments;//lsmLines; // + + TGLPipe(GLPipe).Nodes.AddNode(cp3.x * factor, cp3.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp3.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp4.x * factor, cp4.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp4.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp4.x * factor, (cp4.z + WireTrayHeight)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp4.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp3.x * factor, (cp3.z + WireTrayHeight)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp3.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp3.x * factor, cp3.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp3.y * factor); + + end; + { //дно лотка с шагом в 10 см TGLPipe(GLPipe).Nodes.AddNode(ap1.x * factor, ap1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap1.y * factor); TGLPipe(GLPipe).Nodes.AddNode(ap2.x * factor, ap2.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap2.y * factor); @@ -3831,28 +4118,12 @@ var Dispose(p1); Dispose(p2); end; - + } //TGLPipe(GLPipe).Nodes.AddNode(ap2.x * factor, ap2.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap2.y * factor); //TGLPipe(GLPipe).Nodes.AddNode(ap3.x * factor, ap3.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), ap3.y * factor); - if GLPipe.Material.Texture.Disabled then - begin - ComponColor := getLineComponColor(aCompon);//ConvertWinColor(clGreen); - GLPipe.Material.FrontProperties.Ambient.Color := ComponColor; - GLPipe.Material.FrontProperties.Diffuse.Color := ComponColor; - GLPipe.Material.FrontProperties.Emission.Color := ComponColor; - GLPipe.Material.BackProperties.Ambient.Color := ComponColor; - GLPipe.Material.BackProperties.Diffuse.Color := ComponColor; - GLPipe.Material.BackProperties.Emission.Color := ComponColor; - end; - GLPipe.Material.MaterialOptions := []; - //GLPipe.Material.Texture.Disabled := False; - GLPipe.Material.Texture.Disabled := true; - GLPipe.TagObject := ChildNode; - F3DLineCompon.FGLObject := GLPipe; - TGLPipe(GLPipe).ObjectStyle := TGLPipe(GLPipe).ObjectStyle + [osDirectDraw]; - TGLPipe(GLPipe).SplineMode := lsmSegments;//lsmLines; // + { if WireTrayHeight > 0 then //если задана высота, рисуем боковушки begin HalfWidth := WireTrayHeight; @@ -3952,7 +4223,8 @@ var end else begin - while WireStep < aLine.LineLength do + //while WireStep < aLine.LineLength do + while (compareValue(WireStep, aLine.LineLength) = -1) do begin F3DLineCompon := T3DLineComponent.Create(nil, nil,Self.F3DModel); Self.F3DModel.FScsObjects.Add(F3DLineCompon); @@ -4004,6 +4276,7 @@ var end; end; end; + } // end; end; @@ -7111,6 +7384,8 @@ end; function Tfrm3D.MyGetPickedObject(x, y : Integer): TGLBaseSceneObject; var pkList : TGLPickList; + ComponID: integer; + i: integer; // Tolik 20/05/2025 -- begin pkList := GlsceneViewer.Buffer.GetPickedObjects(Rect(x - 5, y - 5, x + 5, y + 5)); try @@ -7120,6 +7395,40 @@ begin finally pkList.Free; end; + //Tolik 20/05/2025 -- в связи с тем, что объекты не все в основном дереве теперь, тут будем делать подмену, если + // попали на дубль или составной объект, чтобы точно получить трассу или коннектор для сдвига + if Result <> nil then + begin + if Result is TGLPipe then + begin + ComponId := -1; + if TObject(TTreeNode(Result.TagObject).data).ClassName = 'T3DLineComponent' then + begin + if T3DLineComponent(TTreeNode(Result.TagObject).data).FSCSCompon <> nil then + ComponId := T3DLineComponent(TTreeNode(Result.TagObject).data).FSCSCompon.ID; + end; + if ComponID <> -1 then + begin + for i := 0 to SCSModelTree.Items.Count - 1 do + begin + if TObject(TTreeNode(SCSModelTree.Items[i]).Data).ClassNAme = 'T3DLineComponent' then + begin + if T3DLineComponent(TTreeNode(SCSModelTree.Items[i]).Data).FSCSCompon <> nil then + begin + if T3DLineComponent(TTreeNode(SCSModelTree.Items[i]).Data).FSCSCompon.ID = ComponID then + begin + if T3DLineComponent(TTreeNode(SCSModelTree.Items[i]).Data).FGLObject <> nil then + begin + Result := TGLBaseSceneObject(T3DLineComponent(TTreeNode(SCSModelTree.Items[i]).Data).FGLObject); + break; + end; + end; + end; + end; + end; + end; + end; + end; end; @@ -9131,10 +9440,19 @@ begin end; procedure Tfrm3D.FormCreate(Sender: TObject); +const + //OffsetX = 100; + //OffsetY = -50; + Step = 30; var //xModelNode: TFlyNode; RootNode : TTreeNode; ini_file: TIniFile; // Tolik 03/10/2019 -- + arrow: TGLArrowLine; + textObj: TGLSpaceText; + dummy: TGLDummyCube; + offsetX, offsetY: Integer; + i: Integer; // Tolik 03/10/2019 -- function GetIniPath: String; begin @@ -9145,7 +9463,65 @@ var {$ifend} end; // + begin + //Tolik 27/05/2025 -- + // Создаем HUD-Dummy, который всегда будет в одном месте + dummy := TGLDummyCube.Create(GLScene.Objects); + dummy.Pitch(90); // Ориентация камеры + dummy.Position.SetPoint(1, -0.8, -5); // Позиция относительно камеры + dummy.Scale.AsVector := VectorMake(0.1, 0.1, 0.1); // Масштабируем всё + + offsetX := 0; + offsetY := 0; + + // === Стрелка X+ === + arrow := TGLArrowLine(dummy.AddNewChild(TGLArrowLine));//TGLArrowLine.Create(dummy.Objects); + arrow.Direction.AsVector := VectorMake(1, 0, 0); + //arrow.LineColor := clrRed; + arrow.BottomRadius := 2; + arrow.TopArrowHeadHeight := 0.3; + arrow.Material.BackProperties.Diffuse.Alpha := 0.5; + arrow.Material.FrontProperties.Diffuse.Alpha := 0.5; + //arrow.AlphaBlend := True; + //arrow.AlphaBlendValue := 128; + arrow.Position.AsVector := VectorMake(offsetX, offsetY, 0); + + textObj := TGLSpaceText(dummy.AddNewChild(TGLSpaceText)); + textObj.Text := ' X+'; + //textObj.Billboard := True; // Смотрит в камеру + //textObj.Font.Color := clrRed; + textObj.Font.Size := 10; + textObj.Position.AsVector := VectorMake(offsetX + 0.3, offsetY, 0); + //textObj.DepthWriteEnabled := False; + textObj.Material.BackProperties.Diffuse.Alpha := 0.5; + textObj.Material.FrontProperties.Diffuse.Alpha := 0.5; + + Inc(offsetY, -1); + { + // === Стрелка X- === + arrow := TGLArrowLine.Create(dummy.Objects); + arrow.Direction.AsVector := VectorMake(-1, 0, 0); + arrow.LineColor := $000000FF; + arrow.Width := 2; + arrow.HeadLength := 0.3; + arrow.AlphaBlend := True; + arrow.AlphaBlendValue := 128; + arrow.Position.AsVector := VectorMake(offsetX, offsetY, 0); + + textObj := TGLText.Create(dummy.Objects); + textObj.Text := ' X-'; + textObj.Billboard := True; + textObj.Color := $000000FF; + textObj.Font.Size := 10; + textObj.Position.AsVector := VectorMake(offsetX + 0.3, offsetY, 0); + textObj.DepthWriteEnabled := False; + textObj.AlphaBlend := True; + textObj.AlphaBlendValue := 128; + + Inc(offsetY, -1); + } + // DuplicateNodeTree.Visible := False; FMode := F3DPerspective; // Tolik 11/02/2020 @@ -11979,7 +12355,7 @@ end; // Tolik 16/10/2018 -- старая закомменчена -- см ниже procedure Tfrm3D.GLCadencerProgress(Sender: TObject; const deltaTime, newTime: Double); var - i: integer; + i, j: integer; speed : Single; Pt: TPoint; //Alex @@ -11994,8 +12370,12 @@ var ParentNode: TTreeNode; Shift: TShiftState; OldAngle: Double; + currNode: TTreeNode; klPress: integer; + SCSLine: TOrthoLine; + SCSConnector: TConnectorObject; + ConnToMove1, ConntoMove2: T3DConnector; function GetParentConnector(aNode: TTreeNode): T3DConnector; begin @@ -12116,6 +12496,13 @@ var (CompareValue(MinFloorHeight, ParentConnector.FPoint.z*Factor*FScaleDeltaSCS + aCompon.FOffset.y*Factor*FScaleDeltaSCS + dp.y*Factor*FScaleDeltaSCS) > 0)) then Result := False; end; + //Tolik 26/05/2025 -- + function GetParentNode(aNode: TTreeNode): TTreeNode; + begin + Result := aNode; + while Result.Level > 2 do + Result := Result.Parent; + end; begin //if not GLSceneViewer.Focused then @@ -12300,6 +12687,29 @@ begin dp.y := dp.y - MoveDelta; CanMoveObj := True; end; + //Tolik 21/05/2025-- Клавиши ни х сюда не приходят ... сканкоды "простых" калвиш какого-то х приходят на кейпресс формы, + // а вот контролы - как раз сюда... вот хз + 5: //Движение вперед по клавишам ц и w + begin + dp.z := dp.z + MoveDelta; + CanMoveObj := True; + end; + 6: //Движение назад по клавишам ы и s + begin + dp.z := dp.z - MoveDelta; + CanMoveObj := True; + end; + 3: //Поворот влево по клавишам ф и a + begin + dp.x := dp.x - MoveDelta; + CanMoveObj := True; + end; + 4: //Поворот вправо по клавишам в и d + begin + dp.x := dp.x + MoveDelta; + CanMoveObj := True; + end; + // 7: //Движение вперед по клавишам ц и w begin dp.z := dp.z + MoveDelta; @@ -12426,23 +12836,157 @@ begin end else begin - case klPress of - 7: //Движение вперед по клавишам ц и w + if FSelection.Count > 0 then // если выбран объект, при нажатии клавиш - будем его двигать + begin + dp.x := 0; + dp.y := 0; + dp.z := 0; + + case klPress of + 1: //Вверх + begin + dp.y := dp.y + MoveDelta; + CanMoveObj := True; + end; + 2: //Вниз + begin + dp.y := dp.y - MoveDelta; + CanMoveObj := True; + end; + //Tolik 21/05/2025-- Клавиши ни х сюда не приходят ... сканкоды "простых" калвиш какого-то х приходят на кейпресс формы, + // а вот контролы - как раз сюда... вот хз + 5: //Движение вперед по клавишам ц и w + begin + dp.z := dp.z - MoveDelta; + CanMoveObj := True; + end; + 6: //Движение назад по клавишам ы и s + begin + dp.z := dp.z + MoveDelta; + CanMoveObj := True; + end; + 3: //Поворот влево по клавишам ф и a + begin + dp.x := dp.x - MoveDelta; + CanMoveObj := True; + end; + 4: //Поворот вправо по клавишам в и d + begin + dp.x := dp.x + MoveDelta; + CanMoveObj := True; + end; + // + end; + if CanMoveObj then + begin + //MovedConn: T3DConnector; + //MovedComponent: T3DComponent; + + if TglBaseSceneObject(FSelection[0]).TagObject <> nil then begin - GLSceneViewer.Camera.Move(5 * deltaTime); - end; - 8: //Движение назад по клавишам ы и s - begin - GLSceneViewer.Camera.Move(-5 * deltaTime); - end; - 9: //Поворот влево по клавишам ф и a - begin - GLSceneViewer.Camera.slide(-5 * deltaTime); - end; - 10: //Поворот вправо по клавишам в и d - begin - GLSceneViewer.Camera.slide(5 * deltaTime); + currNode := TTreeNode(TglBaseSceneObject(FSelection[0]).TagObject); + ParentNode := GetParentNode(currNode); + //Если выбран линейный объект, получаем трассу, и двигаем ее коннекторы + if TObject(ParentNode.Data).ClassName = 'T3DLine' then + begin + if T3DLine(ParentNode.Data).FGLObject <> nil then + begin + Move3DConnector(T3DConnector(T3DLine(ParentNode.Data).FJoinConnector1), dp); + FMovedObjectsList.Remove(T3DConnector(T3DLine(ParentNode.Data).FJoinConnector1)); + Move3DConnector(T3DConnector(T3DLine(ParentNode.Data).FJoinConnector2), dp); + FMovedObjectsList.Remove(T3DConnector(T3DLine(ParentNode.Data).FJoinConnector2)); + { + if TObject(T3DLine(ParentNode.Data).FGLObject).ClassName = 'TGLLines' then + begin + MovedStartPos1.x := TGLLines(T3DLine(ParentNode.Data).FGLObject).Nodes[0].X + dp.x; + MovedStartPos1.y := TGLLines(T3DLine(ParentNode.Data).FGLObject).Nodes[0].Y + dp.y; + MovedStartPos1.z := TGLLines(T3DLine(ParentNode.Data).FGLObject).Nodes[0].Z + dp.z; + + MovedStartPos2.x := TGLLines(T3DLine(ParentNode.Data).FGLObject).Nodes[1].X + dp.x; + MovedStartPos2.y := TGLLines(T3DLine(ParentNode.Data).FGLObject).Nodes[1].Y + dp.y; + MovedStartPos2.z := TGLLines(T3DLine(ParentNode.Data).FGLObject).Nodes[0].Z + dp.z; + end; + Move3DLineEvent(TglBaseSceneObject(T3DLine(ParentNode.Data).FGLObject)); + } + + end; + { + if T3DLine(ParentNode.Data).FSCSCompon <> nil then + begin + SCSLine := TOrthoLine(T3DLine(ParentNode.Data).FSCSCompon); + SCSConnector := TConnectorObject(SCSLine.JoinConnector1); + + ConnToMove1 := nil; + ConnToMove2 := nil; + + for j := 0 to ScsModelTree.Items.Count - 1 do + begin + if TObject(TTreeNode(SCSModelTree.Items[j]).Data).ClassName = 'T3DConnector' then + begin + if T3DConnector(TTreeNode(SCSModelTree.Items[j]).Data).FSCSCompon <> nil then + begin + if T3DConnector(TTreeNode(SCSModelTree.Items[j]).Data).FSCSCompon.ID = SCSConnector.ID then + begin + ConnToMove1 := T3DConnector(TTreeNode(SCSModelTree.Items[j]).Data); + break; + end; + end; + end; + end; + + SCSConnector := TConnectorObject(SCSLine.JoinConnector2); + + for j := 0 to ScsModelTree.Items.Count - 1 do + begin + if TObject(TTreeNode(SCSModelTree.Items[j]).Data).ClassName = 'T3DConnector' then + begin + if T3DConnector(TTreeNode(SCSModelTree.Items[j]).Data).FSCSCompon <> nil then + begin + if T3DConnector(TTreeNode(SCSModelTree.Items[j]).Data).FSCSCompon.ID = SCSConnector.ID then + begin + ConnToMove2 := T3DConnector(TTreeNode(SCSModelTree.Items[j]).Data); + break; + end; + end; + end; + end; + + if ConnToMove1 <> nil then + Move3DConnector(ConnToMove1, dp); + if ConnToMove2 <> nil then + Move3DConnector(ConnToMove2, dp); + end; + } + end + else + if TObject(ParentNode.Data).ClassName = 'T3DConnector' then + begin + Move3DConnector(T3DConnector(ParentNode.Data), dp); + FMovedObjectsList.Remove(T3DConnector(ParentNode.Data)); + end; end; + end; + end + else //Tolik 26/05/2025 -- это если выбранного объекта нет (тогда просто едет камера) + begin + case klPress of + 7: //Движение вперед по клавишам ц и w + begin + GLSceneViewer.Camera.Move(5 * deltaTime); + end; + 8: //Движение назад по клавишам ы и s + begin + GLSceneViewer.Camera.Move(-5 * deltaTime); + end; + 9: //Поворот влево по клавишам ф и a + begin + GLSceneViewer.Camera.slide(-5 * deltaTime); + end; + 10: //Поворот вправо по клавишам в и d + begin + GLSceneViewer.Camera.slide(5 * deltaTime); + end; + end; end; if klPress > 10 then @@ -21846,14 +22390,696 @@ var SCSLineList.Free; end; // + //Tolik 21/05/2025-- + Procedure CheckRecreateWireTrays; //если на трассах будут проволочные лотки, то их все нужно пересоздать для пересчета + // координат всех составляющих + var i, j, k: Integer; + MainTray, delObj: TglPipe; + ConnTraceList, delNodeList, delObjectList, delComponList: TList; + SCSCatalog: TSCSCatalog; + SCSConn: TConnectorObject; + SCSLine: TOrthoLine; + WireTray: TSCSComponent; + nodetodel, MainTrayNode: TTreeNode; + ComponToDel: T3dLineComponent; + WireTrayWidth, WireTrayHeight: double; + GLPipe: TGLFreeForm; + ap: T3DPointArray; + ap1, ap2, ap3, ap4, ap5, ap6, ap7, ap8: TDoublePoint; + p1,p2: PDoublePoint; + LineComponProp: PProperty; + HalfWidth, WireStep: Double; + WireNode: TTreeNode; + GLTray: TGLFreeForm; + cp1, cp2, cp3,cp4, cp5, cp6: TDoublepoint; + F3DLineCompon: T3DLineComponent; + ComponColor: Tvector4f; + WireTrayPipe: TGLPipe; + Curr3DLine, Left3dLine, Right3DLine: T3DLine;// это уже трасса на 3Д (с учетом того, куда могла поехать, координаты будут в ней пересчитаны и для када) + //Tolik 13/05/2025 -- + Procedure CheckInterSection(aSide: integer); + var i: integer; + LineList: TList; + AngleArray: array of double; + LineConn: TConnectorObject; + currLine: TOrthoLine; + LineCatalog: TSCSCatalog; + LineAngle: Double; + canExchange: Boolean; + Point1, Point2: TDoublePoint; + LeftLine, RightLine: TOrthoLine; + LeftWireTray, RightWireTray: TSCSComponent; + SCSCatalog: TSCSCatalog; + CrossWarewidth: Double; + crPoint1, crPoint2: TDoublePoint; + Curr3DLine, Left3dLine, Right3DLine: T3DLine;// это уже трасса на 3Д (с учетом того, куда могла поехать, координаты будут в ней пересчитаны и для када) + + Procedure SetCrossPoint(acrossSide: integer); //Tolik 15/05/2025 -- расчет точки пересечения + var A1, B1, C1, A2, B2, C2: Double; + Denominator, X, Y: Double; + begin + // Вычисляем коэффициенты для первой прямой (A1x + B1y + C1 = 0) + if aSide = 1 then + begin + if (acrossSide = 1) then //(левое пересечение) + begin + A1 := cp3.Y - cp4.Y; + B1 := cp4.X - cp3.X; + C1 := -A1 * cp4.X - B1 * cp4.Y; + end; + if (acrossSide = 2) then //(правое пересечение) + begin + A1 := cp1.Y - cp6.Y; + B1 := cp6.X - cp1.X; + C1 := -A1 * cp6.X - B1 * cp6.Y; + end; + end; + if aSide = 2 then + begin + // Вычисляем коэффициенты для первой прямой (A1x + B1y + C1 = 0) + if (acrossSide = 1) then //(левое пересечение) + begin + A1 := cp6.Y - cp1.Y; + B1 := cp1.X - cp6.X; + C1 := -A1 * cp1.X - B1 * cp1.Y; + end; + if (acrossSide = 2) then //(правое пересечение) + begin + A1 := cp4.Y - cp3.Y; + B1 := cp3.X - cp4.X; + C1 := -A1 * cp3.X - B1 * cp3.Y; + end; + end; + + // Вычисляем коэффициенты для второй прямой (A2x + B2y + C2 = 0) + A2 := ap1.Y - ap4.Y; + B2 := ap4.X - ap1.X; + C2 := -A2 * ap4.X - B2 * ap4.Y; + + // Вычисляем знаменатель + Denominator := A1 * B2 - A2 * B1; + //если не на одной прямой + if CompareValue(ABS(Denominator), 0.01) <> -1 then + begin + // Находим точку пересечения + if aSide = 1 then + begin + if aCrossSide = 1 then + begin + cp3.X := (B1 * C2 - B2 * C1) / Denominator; + cp3.Y := (A2 * C1 - A1 * C2) / Denominator; + end + else + if aCrossSide = 2 then + begin + cp1.X := (B1 * C2 - B2 * C1) / Denominator; + cp1.Y := (A2 * C1 - A1 * C2) / Denominator; + end; + end + else + if aSide = 2 then + begin + if aCrossSide = 1 then + begin + cp6.X := (B1 * C2 - B2 * C1) / Denominator; + cp6.Y := (A2 * C1 - A1 * C2) / Denominator; + end + else + if aCrossSide = 2 then + begin + cp4.X := (B1 * C2 - B2 * C1) / Denominator; + cp4.Y := (A2 * C1 - A1 * C2) / Denominator; + end; + end; + end; + end; + begin + SetLength(AngleArray, 0); + LeftWireTray := nil; + RightWireTray := nil; + if aSide = 1 then + LineConn := TConnectorObject(SCSLine.JoinConnector1) + else + LineConn := TConnectorObject(SCSLine.JoinConnector2); + + LineList := TList.Create; + + if LineConn.JoinedConnectorsList.Count = 0 then + begin + //список трасс на коннекторе + for i := 0 to LineConn.JoinedOrtholinesList.Count - 1 do + begin + currLine := TOrthoLine(LineConn.JoinedOrtholinesList[i]); + LineList.Add(currLine); + end; + + //если других трасс нет - перерасчет точек не нужен + if LineList.Count = 1 then + begin + + end + else + //если две, то соседние искать не нужно + if LineList.Count = 2 then + begin + LeftLine := nil; + RightLine := nil; + if TOrthoLine(LineList[0]).ID = SCSLine.ID then + LeftLine := TOrthoLine(LineList[1]) + else + LeftLine := TOrthoLine(LineList[0]); + + SCSCatalog := F_ProjMan.GSCSBase.CurrProject.GetCatalogFromReferencesBySCSID(LeftLine.ID); + if SCSCatalog <> nil then + begin + for i := 0 to SCSCatalog.ComponentReferences.Count - 1 do + begin + if SCSCatalog.ComponentReferences[i].ComponentType.SysName = ctsnWireTray then + begin + LeftWireTray := SCSCatalog.ComponentReferences[i]; + break; + end; + end; + end; + + if LeftWireTray <> nil then + begin + RightWireTray := LeftWireTray; + RightLine := LeftLine; + end; + end + else //здесь 3 и более (для каждой нужно искать соседнюю левую и соседнюю правую) + begin + setLength(angleArray, LineList.Count); // углы наклона трасс + for i := 0 to LineList.Count - 1 do + begin + currLine := TOrthoLine(LineList[i]); + if currLine.JoinConnector1.ID = LineConn.ID then + LineAngle := currLine.GetAngleDF(TConnectorObject(currLine.JoinConnector1).ap1.x, TConnectorObject(currLine.JoinConnector1).ap1.y, + TConnectorObject(currLine.JoinConnector2).ap1.x, TConnectorObject(currLine.JoinConnector2).ap1.y) + else + LineAngle := currLine.GetAngleDF(TConnectorObject(currLine.JoinConnector2).ap1.x, TConnectorObject(currLine.JoinConnector2).ap1.y, + TConnectorObject(currLine.JoinConnector1).ap1.x, TConnectorObject(currLine.JoinConnector1).ap1.y); + angleArray[i] := LineAngle; + end; + //сортировка + CanExchange := True; + while CanExchange do + begin + CanExchange := False; + for i := 0 to LineList.Count - 2 do + begin + LineAngle := angleArray[i]; + if CompareValue(LineAngle, angleArray[i + 1]) = 1 then + begin + CanExchange := true; + LineList.Exchange(i, i+1); + angleArray[i] := angleArray[i + 1]; + angleArray[i + 1] := LineAngle; + break; + end; + end; + end; + //здесь берем две соседние трассы с текущей из списка + for i := 0 to LineList.Count - 1 do + begin + if TOrthoLine(LineList[i]).ID = SCSLine.ID then + begin + if i = 0 then + begin + LeftLine := TOrthoLine(LineList[i + 1]); + RightLine := TOrthoLine(LineList[LineList.Count - 1]); + end + else + if i = (LineList.Count - 1) then + begin + LeftLine := TOrthoLine(LineList[0]); + RightLine := TOrthoLine(LineList[i - 1]); + end + else + begin + LeftLine := TOrthoLine(LineList[i + 1]); + RightLine := TOrthoLine(LineList[i - 1]); + end; + break; + end; + end; + //ищем лотки справа и слева + LeftWireTray := nil; + RightWireTray := nil; + + SCSCatalog := F_ProjMan.GSCSBase.CurrProject.GetCatalogFromReferencesBySCSID(LeftLine.ID); + if SCSCatalog <> nil then + begin + for i := 0 to SCSCatalog.ComponentReferences.Count - 1 do + begin + if SCSCatalog.ComponentReferences[i].ComponentType.SysName = ctsnWireTray then + begin + LeftWireTray := SCSCatalog.ComponentReferences[i]; + break; + end; + end; + end; + + SCSCatalog := F_ProjMan.GSCSBase.CurrProject.GetCatalogFromReferencesBySCSID(RightLine.ID); + if SCSCatalog <> nil then + begin + for i := 0 to SCSCatalog.ComponentReferences.Count - 1 do + begin + if SCSCatalog.ComponentReferences[i].ComponentType.SysName = ctsnWireTray then + begin + RightWireTray := SCSCatalog.ComponentReferences[i]; + break; + end; + end; + end; + end; + //Tolik 15/05/2025 -- левый лоток(если задана ширина) + if LeftWireTray <> nil then + begin + WireTrayWidth := 0; + LineComponProp := LeftWireTray.GetPropertyBySysName(pnWidth); + if LineComponProp <> nil then + WireTrayWidth := LeftWireTray.GetPropertyValueAsFloat(pnWidth); + if WireTrayWidth <> 0 then + begin + HalfWidth := WireTrayWidth/2; + + p1 := GetPoint(LeftLine, 1, HalfWidth); + p2 := GetPoint(LeftLine, 2, HalfWidth); + //если пересечение на коннекторе1 + if LineConn.ID = LeftLine.JoinConnector1.ID then + begin + ap1 := RotatePoint(LeftLine.ap1, p1^, -PI/2); + ap4 := RotatePoint(LeftLine.ap2, p2^, PI/2); + end + else + begin // на втором коннекторе + ap1 := RotatePoint(LeftLine.ap2, p2^, -PI/2); + ap4 := RotatePoint(LeftLine.ap1, p1^, PI/2); + end; + SetCrossPoint(1); + end; + end; + //Tolik 15/05/2025 -- левый лоток(если задана ширина) + if RightWireTray <> nil then + begin + WireTrayWidth := 0; + LineComponProp := RightWireTray.GetPropertyBySysName(pnWidth); + if LineComponProp <> nil then + WireTrayWidth := RightWireTray.GetPropertyValueAsFloat(pnWidth); + if WireTrayWidth <> 0 then + begin + HalfWidth := WireTrayWidth/2; + + p1 := GetPoint(RightLine, 1, HalfWidth); + p2 := GetPoint(RightLine, 2, HalfWidth); + + //если приходит на первый коннектор: + if LineConn.ID = RightLine.JoinConnector1.ID then + begin + ap1 := RotatePoint(RightLine.ap1, p1^, PI/2); + ap4 := RotatePoint(RightLine.ap2, p2^, -PI/2); + end + else + begin + ap1 := RotatePoint(RightLine.ap2, p2^, PI/2); + ap4 := RotatePoint(RightLine.ap1, p1^, -PI/2); + end; + + //контур поддона лотка Tolik 15/05/2025 -- + { + ap1 := RotatePoint(aLine.ap1, p1^, -PI/2); + ap2 := RotatePoint(aLine.ap1, p1^, PI/2); + ap3 := RotatePoint(aLine.ap2, p2^, -PI/2); + ap4 := RotatePoint(aLine.ap2, p2^, PI/2); + } + SetCrossPoint(2); + end; + end; + end; + + LineList.Free; + SetLength(angleArray, 0); + end; + + + begin + ConnTraceList := TList.Create; + delNodeList := TList.Create; + delObjectList := TList.Create; + delComponList := TList.Create; + + if T3DConnector(aObj).FSCSObject <> nil then + begin + if TConnectorObject(T3DConnector(aObj).FSCSObject).ConnectorType = ct_Clear then + begin + for i := 0 to TConnectorObject(T3DConnector(aObj).FSCSObject).JoinedOrtholinesList.Count - 1 do + begin + ConnTraceList.Add(TOrthoLine(TConnectorObject(T3DConnector(aObj).FSCSObject).JoinedOrtholinesList[i])); + end; + end; + end; + for i := 0 to ConnTraceList.Count - 1 do + begin + SCSLine := TOrthoLine(ConnTraceList[i]); + SCSCatalog := F_ProjMan.GSCSBase.CurrProject.GetCatalogFromReferencesBySCSID(SCSLine.ID); + if SCSCatalog <> nil then + begin + WireTray := nil; + for j := 0 to SCSCatalog.ComponentReferences.Count - 1 do + begin + if SCSCatalog.ComponentReferences[j].ComponentType.SysName = ctsnWireTray then + begin + WireTray := SCSCatalog.ComponentReferences[j]; + break; + end; + end; + if WireTray <> nil then // если на присоединенной трассе есть лоток - пересоздаем + begin + Curr3DLine := nil; + //Координаты СКС трассы для пересчета тут уже неактуальны, т.к. она могла уже "уехать" (двинул пользователь пару раз) + for j := 0 to SCSModelTree.Items.Count - 1 do + begin + if TObject(SCSModelTree.Items[j].Data).ClassNAme = 'T3DLine' then + begin + if T3DLine(SCSModelTree.Items[j].Data).FSCSCompon.ID = SCSLine.ID then + begin + Curr3DLine := T3DLine(SCSModelTree.Items[j].Data); + break; + end; + end; + end; + //выбираем компоненты лотка + MainTrayNode := nil; + for j := 0 to SCSModelTree.Items.Count - 1 do + begin + if TObject(SCSModelTree.Items[j].Data).ClassNAme = 'T3DLineComponent' then + begin + if T3DLineComponent(SCSModelTree.Items[j].Data).FSCSCompon.ID = WireTray.ID then + begin + MainTrayNode := SCSModelTree.Items[j]; + break; + end; + end; + end; + + for j := 0 to DuplicateNodeTree.Items.Count - 1 do + begin + if TObject(DuplicateNodeTree.Items[j].Data).ClassName = 'T3DLineComponent' then + begin + if T3DLineComponent(DuplicateNodeTree.Items[j].Data).FSCSCompon.ID = WireTray.ID then + begin + delObjectList.Add(T3DLineComponent(DuplicateNodeTree.Items[j].Data).FGLObject);//объект для удаления с 3Д + delNodeList.Add(TTreeNode(DuplicateNodeTree.Items[j])); // объекты для удаления из вспомогательного дерева + delComponList.Add(T3DLineComponent(DuplicateNodeTree.Items[j].Data)); // клмплненты для удаления из списка объектов модели + end; + end; + end; + //Удаляем + //TglPipe(T3DComponent(MainTrayNode.Data).FGLObject).Nodes.Clear; + for j := 0 to delObjectList.Count - 1 do + begin + delObj := TGLPipe(delObjectList[j]); + nodeTodel := TTreeNode(delNodeList[j]); + ComponToDel := T3DLineComponent(delComponList[j]); + NodeTodel.Data := nil; + dummycube.Remove(delObj, false); + delObj.Free; + DuplicateNodeTree.Items.Delete(nodeToDel); + F3DModel.FScsObjects.Remove(ComponToDel); + ComponToDel.Free; + end; + delNodeList.Clear; + delObjectList.Clear; + delComponList.Clear; + + //пересоздаем лоток по новым координатам + WireTrayWidth := 0; + WireTrayHeight := 0; + SetLength(ap, 0); + + LineComponProp := WireTray.GetPropertyBySysName(pnWidth); + if LineComponProp <> nil then + WireTrayWidth := WireTray.GetPropertyValueAsFloat(pnWidth); + + LineComponProp := WireTray.GetPropertyBySysName(pnHeight); + if LineComponProp <> nil then + WireTrayHeight := WireTray.GetPropertyValueAsFloat(pnHeight); + + if WireTrayWidth <> 0 then + begin + HalfWidth := WireTrayWidth/2; + + p1 := GetPoint(SCSLine, 1, HalfWidth); + p2 := GetPoint(SCSLine, 2, HalfWidth); + //контур поддона лотка Tolik 15/05/2025 -- + cp1 := RotatePoint(SCSLine.ap1, p1^, -PI/2); + cp1.z := p1.z; + cp2 := SCSLine.ap1; + cp2.z := p1.z; + cp3 := RotatePoint(SCSLine.ap1, p1^, PI/2); + cp3.z := p1.z; + cp4 := RotatePoint(SCSLine.ap2, p2^, -PI/2); + cp4.z := p2.z; + cp5 := SCSLine.ap2; + cp5.z := p2.z; + cp6 := RotatePoint(SCSLine.ap2, p2^, PI/2); + cp6.z := p2.z; + { + ap1 := RotatePoint(aLine.ap1, p1^, -PI/2); + ap2 := RotatePoint(aLine.ap1, p1^, PI/2); + + ap3 := RotatePoint(aLine.ap2, p2^, -PI/2); + ap4 := RotatePoint(aLine.ap2, p2^, PI/2); + } + CheckInterSection(1); //Tolik 13/05/2025 -- + CheckInterSection(2); + + WireTrayPipe := TGLPipe(T3dLineComponent(MainTrayNode.Data).FGLObject); + + WireTrayPipe.Nodes[0].X := cp1.x * factor; + WireTrayPipe.Nodes[0].y := cp1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)); + WireTrayPipe.Nodes[0].z := cp1.y * factor; + + WireTrayPipe.Nodes[1].X := cp2.x * factor; + WireTrayPipe.Nodes[1].y := cp2.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)); + WireTrayPipe.Nodes[1].z := cp2.y * factor; + + WireTrayPipe.Nodes[2].X := cp3.x * factor; + WireTrayPipe.Nodes[2].y := cp3.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)); + WireTrayPipe.Nodes[2].z := cp3.y * factor; + + WireTrayPipe.Nodes[3].X := cp4.x * factor; + WireTrayPipe.Nodes[3].y := cp4.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)); + WireTrayPipe.Nodes[3].z := cp4.y * factor; + + WireTrayPipe.Nodes[4].X := cp5.x * factor; + WireTrayPipe.Nodes[4].y := cp5.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)); + WireTrayPipe.Nodes[4].z := cp5.y * factor; + + WireTrayPipe.Nodes[5].X := cp6.x * factor; + WireTrayPipe.Nodes[5].y := cp6.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)); + WireTrayPipe.Nodes[5].z := cp6.y * factor; + + WireTrayPipe.Nodes[6].X := cp1.x * factor; + WireTrayPipe.Nodes[6].y := cp1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)); + WireTrayPipe.Nodes[6].z := cp1.y * factor; + + { + TGLPipe(GLPipe).Nodes.AddNode(cp1.x * factor, cp1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp1.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp2.x * factor, cp2.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp2.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp3.x * factor, cp3.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp3.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp4.x * factor, cp4.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp4.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp5.x * factor, cp5.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp5.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp6.x * factor, cp6.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp6.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp1.x * factor, cp1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp1.y * factor); + } + //боковушки + if WireTrayHeight <> 0 then + begin + //правая + F3DLineCompon := T3DLineComponent.Create(nil, nil,Self.F3DModel); + Self.F3DModel.FScsObjects.Add(F3DLineCompon); + childNode := DuplicateNodeTree.Items.AddChild(nil, WireTray.GetNameForVisible); + childNode.ImageIndex := 8; + childNode.SelectedIndex := 2; + ChildNode.Data := F3DLineCompon; + F3DLineCompon.FSCSCompon := WireTray; + F3DLineCompon.FSCSComponID := WireTray.ID; + + GLPipe := TGLFREEFORM(DummyCube.AddNewChild(TGLPipe)); + TGLPipe(GLPipe).Radius := 0.01 * UOMToMetre(1000 / FCAD.PCad.MapScale) * factor; + + if GLPipe.Material.Texture.Disabled then + begin + ComponColor := getLineComponColor(WireTray);//ConvertWinColor(clGreen); + GLPipe.Material.FrontProperties.Ambient.Color := ComponColor; + GLPipe.Material.FrontProperties.Diffuse.Color := ComponColor; + GLPipe.Material.FrontProperties.Emission.Color := ComponColor; + GLPipe.Material.BackProperties.Ambient.Color := ComponColor; + GLPipe.Material.BackProperties.Diffuse.Color := ComponColor; + GLPipe.Material.BackProperties.Emission.Color := ComponColor; + end; + + GLPipe.Material.MaterialOptions := []; + //GLPipe.Material.Texture.Disabled := False; + GLPipe.Material.Texture.Disabled := true; + GLPipe.TagObject := ChildNode; + F3DLineCompon.FGLObject := GLPipe; + TGLPipe(GLPipe).ObjectStyle := TGLPipe(GLPipe).ObjectStyle + [osDirectDraw]; + TGLPipe(GLPipe).SplineMode := lsmSegments;//lsmLines; // + + TGLPipe(GLPipe).Nodes.AddNode(cp1.x * factor, cp1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp1.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp6.x * factor, cp6.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp6.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp6.x * factor, (cp6.z + WireTrayHeight)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp6.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp1.x * factor, (cp1.z + WireTrayHeight)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp1.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp1.x * factor, cp1.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp1.y * factor); + //Левая + F3DLineCompon := T3DLineComponent.Create(nil, nil,Self.F3DModel); + Self.F3DModel.FScsObjects.Add(F3DLineCompon); + childNode := DuplicateNodeTree.Items.AddChild(nil, WireTray.GetNameForVisible); + childNode.ImageIndex := 8; + childNode.SelectedIndex := 2; + ChildNode.Data := F3DLineCompon; + F3DLineCompon.FSCSCompon := WireTray; + F3DLineCompon.FSCSComponID := WireTray.ID; + + GLPipe := TGLFREEFORM(DummyCube.AddNewChild(TGLPipe)); + TGLPipe(GLPipe).Radius := 0.01 * UOMToMetre(1000 / FCAD.PCad.MapScale) * factor; + + if GLPipe.Material.Texture.Disabled then + begin + ComponColor := getLineComponColor(WireTray);//ConvertWinColor(clGreen); + GLPipe.Material.FrontProperties.Ambient.Color := ComponColor; + GLPipe.Material.FrontProperties.Diffuse.Color := ComponColor; + GLPipe.Material.FrontProperties.Emission.Color := ComponColor; + GLPipe.Material.BackProperties.Ambient.Color := ComponColor; + GLPipe.Material.BackProperties.Diffuse.Color := ComponColor; + GLPipe.Material.BackProperties.Emission.Color := ComponColor; + end; + + GLPipe.Material.MaterialOptions := []; + //GLPipe.Material.Texture.Disabled := False; + GLPipe.Material.Texture.Disabled := true; + GLPipe.TagObject := ChildNode; + F3DLineCompon.FGLObject := GLPipe; + TGLPipe(GLPipe).ObjectStyle := TGLPipe(GLPipe).ObjectStyle + [osDirectDraw]; + TGLPipe(GLPipe).SplineMode := lsmSegments;//lsmLines; // + + TGLPipe(GLPipe).Nodes.AddNode(cp3.x * factor, cp3.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp3.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp4.x * factor, cp4.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp4.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp4.x * factor, (cp4.z + WireTrayHeight)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp4.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp3.x * factor, (cp3.z + WireTrayHeight)* factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp3.y * factor); + TGLPipe(GLPipe).Nodes.AddNode(cp3.x * factor, cp3.z * factor * UOMToMetre(1000 / FCAD.PCad.MapScale) + FZOrder*factor*(UOMToMetre(1000 / FCAD.PCad.MapScale)), cp3.y * factor); + end; + end; + end; + end; + end; + end; + //Tolik 05/06/2025-- при попытке ствига коннектора не дать наехать коннектору на второй коннектолр трассы + // и съехать выше или ниже текущего этажа + + Function CheckCanMoveConn(aConn: T3DConnector):Boolean; + var ParentCatalog: TSCSCatalog; + currCad: TF_CAD; + FloorHeight, MinFloorHeight, MaxFloorHeight : Double; + ListParams: TListParams; + ParentConnector: T3DConnector; + i: integer; + CorrectConn: T3DConnector; + ConnNode, ParentNode: TTreeNode; + CanGetParent: Boolean; + + begin + //Result := True; + Result := False; + currCad := Nil; + + CorrectConn := nil; + ConnNode := nil; + ParentNode := nil; + + if aConn.FSCSComponID > 0 then + begin + //найти коннектор и его узел в дереве + for i := 0 to SCSModelTree.Items.Count - 1 do + begin + if TObject(SCSModelTree.Items[i].data).ClassName = 'T3DConnector' then + begin + if T3DConnector(SCSModelTree.Items[i].data).FSCSComponID > 0 then + begin + if T3DConnector(SCSModelTree.Items[i].data).FSCSComponID = aConn.FSCSComponID then + begin + CorrectConn := T3DConnector(SCSModelTree.Items[i].data); + ConnNode := SCSModelTree.Items[i]; + break; + end; + end; + end; + end; + + if ConnNode = nil then + exit; + end + else + exit; + + //Ищем текущий кад + CanGetParent := true; + ParentNode := ConnNode.Parent; + while CanGetParent do + begin + if TObject(ParentNode.data).ClassName <> 'TF_CAD' then + ParentNode := ParentNode.Parent + else + CanGetParent := False; + end; + + currCad := TF_CAD(ParentNode.Data); + + if CurrCad = nil then + exit; + + + ListParams := GetListParams(currCad.FCADListID); + FloorHeight := MetreToUOM(ListParams.Settings.HeightRoom)*(1000 / currCad.PCad.MapScale)*Factor; // высота этажа + + if ListNotUnderFloor(currCad) then + begin + MaxFloorHeight := Get3DFloorHeight(currCad)*Factor; + MinFloorHeight := MaxFloorHeight - FloorHeight; + end + else + begin + MinFloorHeight := Get3DFloorHeight(currCad)*Factor; + MaxFloorHeight := MinFloorHeight + FloorHeight; + end; + Result := True; + + //Если элемент трубы проверяем высоты и "наезды" + if CorrectConn.FisPipeElement then + begin + + end; + + { + if ((CompareValue(MaxFloorHeight, xConn.FPoint.z*Factor*FScaleDeltaSCS + aCompon.FOffset.y*Factor*FScaleDeltaSCS + dp.y*Factor*FScaleDeltaSCS) < 0) or + (CompareValue(MinFloorHeight, xConn.FPoint.z*Factor*FScaleDeltaSCS + aCompon.FOffset.y*Factor*FScaleDeltaSCS + dp.y*Factor*FScaleDeltaSCS) > 0)) then + Result := False; + } + + end; begin try if (dp.x = 0) and (dp.y = 0) and (dp.z = 0) then exit; xGLObject := nil; xConn := aObj; - + if not CheckCanMoveConn(aObj) then + exit; // Tolik 26/04/2018 -- { if dp.y <> 0 then @@ -22068,6 +23294,25 @@ begin end; end; end; + for k := 0 to DuplicateNodeTree.Items.Count - 1 do + begin + if TObject(TTreeNode(DuplicateNodeTree.Items[k]).Data) is T3DConnector then + begin + if T3DConnector(TTreeNode(DuplicateNodeTree.Items[k]).Data).FSCSObject <> nil then + begin + if T3DConnector(TTreeNode(DuplicateNodeTree.Items[k]).Data).FSCSObject.ID = xConn.FSCSObject.ID then + begin + if T3DConnector(TTreeNode(DuplicateNodeTree.Items[k]).Data).FGLObject <> nil then + begin + if T3DConnector(TTreeNode(DuplicateNodeTree.Items[k]).Data).FGLObject is TGLPipe then + begin + RelatedPipeConns.Add(T3DConnector(TTreeNode(DuplicateNodeTree.Items[k]).Data)); + end; + end; + end; + end; + end; + end; { for l := 0 to RelatedPipeConns.Count - 1 do begin @@ -22385,6 +23630,7 @@ begin end; AlignPipeObjects; AlignRelatedConns; + CheckRecreateWireTrays;//лоток проволочный MovedLineList.free; OtherSideConnList.free; RelatedPipeConns.free; @@ -22972,7 +24218,31 @@ begin // xGLLine.Nodes[1].Y := aPos.y; xGLLine.Nodes[1].Z := aPos.z; + end + //Tolik 28/05/2025 - + else + begin + if xConn.FIndex = xLine.FJoinConnector1.FIndex then + begin + xGLLine.Nodes[0].X := aPos.x; + // Tolik 27/04/2018 -- + if NoTrunkConn then + // + xGLLine.Nodes[0].Y := aPos.y; + xGLLine.Nodes[0].Z := aPos.z; + end + else + if xConn.FIndex = xLine.FJoinConnector2.FIndex then + begin + xGLLine.Nodes[1].X := aPos.x; + // Tolik 27/04/2018 -- + if NoTrunkConn then + // + xGLLine.Nodes[1].Y := aPos.y; + xGLLine.Nodes[1].Z := aPos.z; + end end; + // xLine.FGLPoint1.x := xGLLine.Nodes[0].X; xLine.FGLPoint1.y := xGLLine.Nodes[0].Y - xLine.FZOrder; xLine.FGLPoint1.z := xGLLine.Nodes[0].Z;