mirror of
http://gitlab.expertsoft.com.ua/git/expertcad
synced 2026-01-12 00:45:40 +02:00
4017 lines
123 KiB
ObjectPascal
4017 lines
123 KiB
ObjectPascal
unit U_Arch3D;
|
|
|
|
interface
|
|
uses
|
|
Windows, Forms, StdCtrls, Classes, ComCtrls, Controls, DrawEngine, PCTypesUtils, SysUtils, Dialogs, Math,
|
|
Contnrs, DrawObjects, PCDrawBox, PCDrawing, PowerCad, Graphics, U_Cad, U_ESCadClasess, fplan,
|
|
U_SCSComponent, VectorTypes, rrEllipses;
|
|
|
|
type
|
|
// ìîäåëü
|
|
T3DModel = class;
|
|
// êîìíàòà
|
|
T3DRoom = class;
|
|
// ñòåíà
|
|
T3DWall = class;
|
|
// ýëåìåíò ñòåíû (îêíî, äâåðü, áàëêîí, íèøà, àðêà)
|
|
T3DWallElement = class;
|
|
// ýëåìåíò áàëêîíà (áàëêîííîå îêíî, áàëêîííàÿ äâåðü)
|
|
T3DBalconElement = class;
|
|
// îòêîñ (äâåðíîé, îêîíîííûé, áàëêîííûé)
|
|
T3DSlope = class;
|
|
// ãðàíü (ñòåíû, îêíà, äâåðè, îòêîñà è ò.ä) - ýòî òå îáüåêòû ïîëèãîíîâ è ìýøåé,
|
|
// êîòîðûå äîáàâëÿþòñÿ â Faces è îòðèñîâûâàþòñÿ
|
|
T3DSide = class;
|
|
// îáúåêòû ñ 3ds
|
|
T3DSObject = class;
|
|
|
|
T3DModel = class(TMyObject)
|
|
FClassName: string;
|
|
FName: string;
|
|
FRooms: TList;
|
|
FHashs: TStringList;
|
|
constructor Create;
|
|
function GetObjectBySCSCompon(ASCSCompon: TSCSComponent): TObject;
|
|
procedure WriteToStream(Stream: TStream);
|
|
procedure ReadFromStream(Stream: TStream);
|
|
procedure SetRelations;
|
|
end;
|
|
|
|
T3DRoom = class(TMyObject)
|
|
private
|
|
FParentIndex: Integer;
|
|
public
|
|
FClassName: string;
|
|
FName: string;
|
|
FPlanObject: TNet;
|
|
FSCSCompon: TSCSComponent;
|
|
FSCSComponID: Integer;
|
|
FParent: T3DModel;
|
|
FNetConture: TDoublePointArr;
|
|
FFloorConture: TDoublePointArr;
|
|
FCeilingConture: TDoublePointArr;
|
|
FWalls: TList;
|
|
F3DSObjects: TList;
|
|
FFloor: T3DSide;
|
|
FCeiling: T3DSide;
|
|
FVisible: Boolean;
|
|
constructor Create(aFaces: TList; aNet: TNet; aParent: T3DModel);
|
|
procedure CollectRoom(aFaces: TList);
|
|
procedure CollectFloor(aFaces: TList);
|
|
procedure CollectCeiling(aFaces: TList);
|
|
function GetObjectBySCSCompon(ASCSCompon: TSCSComponent): TObject;
|
|
procedure WriteToStream(Stream: TStream);
|
|
procedure ReadFromStream(Stream: TStream);
|
|
procedure SetRelations;
|
|
end;
|
|
|
|
T3DWall = class(TMyObject)
|
|
private
|
|
FParentIndex: Integer;
|
|
public
|
|
FClassName: string;
|
|
FName: string;
|
|
FPlanObject: TNetPath;
|
|
FSCSCompon: TSCSComponent;
|
|
FSCSComponID: Integer;
|
|
FParent: T3DRoom;
|
|
FWallElements: TList;
|
|
FSides: TList;
|
|
FIsArc: Boolean;
|
|
constructor Create(aFaces: TList; aNetPath: TNetPath; aParent: T3DRoom);
|
|
procedure ParseWall(aFaces: TList);
|
|
function CollectWall(aFaces: TList; ap: T3DPointArray; aAdjoiningList: TList; aWallViewType: TWallViewType): TList;
|
|
procedure CollectWallWithAdjoining(aFaces: TList; ap: T3DPointArray; aAdjoiningList: TList; aWallSideType: TWallSideType);
|
|
function GetFullDoors: TList;
|
|
function GetAdjoiningWalls: TList;
|
|
function CheckAdjoiningWallSide(l1, l2: TDoublePoint): Boolean;
|
|
procedure SetWallTypeToWallSide(aWallSides: TList; aWallSideType: TWallSideType; aWallType: TFaceWallType; aWallElement: T3DWallElement);
|
|
function CalcPointHeight(p1, p2, Point: TDoublePoint; p1h, p2h: Double): Double;
|
|
function GetArcWallPoints(aPoints: T3DPointArray; isWall: boolean = False): T3DPointArray;
|
|
procedure WriteToStream(Stream: TStream);
|
|
procedure ReadFromStream(Stream: TStream);
|
|
procedure SetRelations;
|
|
end;
|
|
|
|
T3DWallElement = class(TMyObject)
|
|
private
|
|
FParentIndex: Integer;
|
|
public
|
|
FClassName: string;
|
|
FName: string;
|
|
FPlanObject: TNetDoor;
|
|
FSCSCompon: TSCSComponent;
|
|
FSCSComponID: Integer;
|
|
FParent: T3DWall;
|
|
FElementType: TDoorObjType;
|
|
FSlopes: TList;
|
|
FBalconElements: TList;
|
|
FSides: TList;
|
|
constructor Create(aFaces: TList; aNetDoor: TNetDoor; aElementType: TDoorObjType; aParent: T3DWall);
|
|
procedure CollectDoor(aFaces: TList; ap: T3DPointArray);
|
|
procedure CollectWindow(aFaces: TList; ap: T3DPointArray);
|
|
procedure CollectBalcon(aFaces: TList; ap1, ap2: T3DPointArray);
|
|
procedure ReplaceArcSides;
|
|
procedure ReplaceNicheSides;
|
|
procedure WriteToStream(Stream: TStream);
|
|
procedure ReadFromStream(Stream: TStream);
|
|
procedure SetRelations;
|
|
end;
|
|
|
|
T3DBalconElement = class(TMyObject)
|
|
private
|
|
FParentIndex: Integer;
|
|
public
|
|
FClassName: string;
|
|
FName: string;
|
|
FSCSCompon: TSCSComponent;
|
|
FSCSComponID: Integer;
|
|
FParent: T3DWallElement;
|
|
FElementType: TDoorObjType;
|
|
FSides: TList;
|
|
constructor Create(aFaces: TList; aElementType: TDoorObjType; aParent: T3DWallElement);
|
|
procedure CollectBalconDoor(aFaces: TList; ap1: T3DPointArray);
|
|
procedure CollectBalconWindow(aFaces: TList; ap2: T3DPointArray);
|
|
procedure WriteToStream(Stream: TStream);
|
|
procedure ReadFromStream(Stream: TStream);
|
|
procedure SetRelations;
|
|
end;
|
|
|
|
T3DSlope = class(TMyObject)
|
|
private
|
|
FParentIndex: Integer;
|
|
public
|
|
FClassName: string;
|
|
FName: string;
|
|
FSCSCompon: TSCSComponent;
|
|
FSCSComponID: Integer;
|
|
FParent: T3DWallElement;
|
|
FSides: TList;
|
|
constructor Create(aFaces: TList; aNetDoor: TNetDoor; aParent: T3DWallElement);
|
|
procedure WriteToStream(Stream: TStream);
|
|
procedure ReadFromStream(Stream: TStream);
|
|
procedure SetRelations;
|
|
end;
|
|
|
|
T3DSide = class(TMyObject)
|
|
private
|
|
FParentIndex: Integer;
|
|
public
|
|
FClassName: string;
|
|
FName: string;
|
|
FDescription: TStringList;
|
|
FParent: TObject;
|
|
FGLObject: TObject;
|
|
FFace: TFaceRecord;
|
|
FFaceType: TFaceType;
|
|
FWallType: TFaceWallType;
|
|
FSideType: TWallSideType;
|
|
FPoints: T3DPointArray;
|
|
FGLPoints: T3DPointArray;
|
|
FColor: TColor;
|
|
FRotate: Integer;
|
|
FMirror: Boolean;
|
|
FAsArc: Boolean;
|
|
FTextureHash: string;
|
|
FTexture_ext: string;
|
|
FSubSides: TList;
|
|
constructor Create(aFaceType: TFaceType; aWallType: TFaceWallType; aSideType: TWallSideType; aParent: TObject);
|
|
procedure CollectWallSide(aFaces: TList; ap: T3DPointArray);
|
|
procedure CollectArcWallSide(aFaces: TList; ap: T3DPointArray);
|
|
procedure CollectWallElementSide(aFaces: TList; ap: T3DPointArray; fTrans: boolean = False);
|
|
procedure WriteToStream(Stream: TStream);
|
|
procedure ReadFromStream(Stream: TStream);
|
|
procedure SetRelations;
|
|
function GetArea: Double;
|
|
end;
|
|
|
|
T3DSObject = class(TMyObject)
|
|
private
|
|
FParentIndex: Integer;
|
|
public
|
|
FClassName: string;
|
|
FName: string;
|
|
FDescription: TStringList;
|
|
FParent: T3DRoom;
|
|
FGLObject: TObject;
|
|
FFace: TFaceRecord;
|
|
FPosition: T3DPoint;
|
|
FScale: T3DPoint;
|
|
FRotate: T3DPoint;
|
|
FPath: string;
|
|
constructor Create(aParent: T3DRoom);
|
|
procedure WriteToStream(Stream: TStream);
|
|
procedure ReadFromStream(Stream: TStream);
|
|
procedure SetRelations;
|
|
end;
|
|
|
|
// ñðàâíåíèå êîîðäèíàò
|
|
function CoordsCMP(p1, p2: TDoublePoint): Boolean;
|
|
// ñðàâíåíèå óãëîâ
|
|
function AnglesCMP(a1, a2: Double): Boolean;
|
|
// ñðàâíåíèå äèñòàíöèè ìåæäó òî÷êàìè
|
|
function PointDistCMP(p: TDoublePoint; aNetPath: TNetPath): Boolean;
|
|
// ïîëó÷èòü òèï ñòåíû ïî òèïó îáüåêòà TNetDoor
|
|
function GetWallTypeByDoorType(aDoor: TNetDoor): TFaceWallType;
|
|
// ïîëó÷èòü òî÷êè ñòåíû ñ ó÷åòîì îòêîñîâ îêíà/äâåðè/áàëêîíà
|
|
procedure GetWallPointsWithSlope(var da1, da2, db1, db2: TDoublePoint; hor_a1, hor_a2, hor_b1, hor_b2: double);
|
|
// ïîëó÷èòü òî÷êè äâåðè/îêíà/áàëêîíà ñ ó÷åòîì îòêîñîâ îêíà/äâåðè/áàëêîíà
|
|
procedure GetDoorPointsWithSlope(var c: TDoublePoint; d: TDoublePoint; depth: double);
|
|
// ïîëó÷èòü ñòðîêó Hash äëÿ ôàéëà òåêñòóðû
|
|
function GetImageHash(aFName: string): string;
|
|
|
|
function GetArcWallPointsAll(aPoints: T3DPointArray; FPlanObject: TNetPath; isWall: boolean = False): T3DPointArray;
|
|
|
|
const
|
|
{TODO}
|
|
FDeltaZ: Double = 0.03;
|
|
FDeltaZFloor: Double = 0.045;
|
|
FDeltaZPlane: Double = 0.032;
|
|
FDeltaZSlope: Double = 0.025;
|
|
|
|
// îòñòóï îò ïîëà
|
|
FFloorDelta: Double = 0.00; //.01
|
|
// îòñòóï äî ïîòîëêà îò âåðõíèõ ãðàíåé ñòåíû
|
|
FFCeilingDelta: Double = 0.00; //.01
|
|
// íà÷àëî ïîñòðîåíèå îáüåêòîâ îêíî, äâåðü, íèøà, áàëêîí
|
|
FStartDoorObject: Double = 0.0; // 0.03
|
|
// îòñòóï îò íèæíåé ãðàíè îáüåêòà äî âåðõíåé ãðàíè ñòåíû
|
|
// íàïðèìåð íàðèñîâàòü êóñîê ñòåíû ïîä îêíîì, ÷òîáû íèæíÿÿ ãðàíü îêíà íå ñëèâàëàñü ñ âåðõíåé ãðàíüþ ñòåíû
|
|
FDoorObjectDelta: Double = 0.0; //.01
|
|
|
|
|
|
|
|
// íàèìåíîâàíèÿ îáüåêòîâ ìîäåëè
|
|
cModel = '3D Ìîäåëü';
|
|
cRoom = 'Êîìíàòà ';
|
|
cWall = 'Ñòåíà ';
|
|
cDoor = 'Äâåðíîé ïðîåì ';
|
|
cWindow = 'Îêîííûé ïðîåì ';
|
|
cBalcon = 'Áàëêîííûé ïðîåì ';
|
|
cNiche = 'Íèøà ';
|
|
cArc = 'Àðêà ';
|
|
cInnerSlope = 'Îòêîñ';
|
|
cOuterSlope = 'Âíåøíèé îòêîñ';
|
|
cSide = 'Ãðàíü ';
|
|
cFloor = 'Ïîë';
|
|
cCeiling = 'Ïîòîëîê';
|
|
cSubSide = 'Ïîäãðàíü ';
|
|
|
|
var
|
|
InnerwallStream: TMemoryStream;
|
|
OuterwallStream: TMemoryStream;
|
|
FloorStream: TMemoryStream;
|
|
CeilingStream: TMemoryStream;
|
|
DoorStream: TMemoryStream;
|
|
WindowStream: TMemoryStream;
|
|
ArcStream: TMemoryStream;
|
|
BalconStream: TMemoryStream;
|
|
NicheStream: TMemoryStream;
|
|
tmpdir, tex_innerwall, tex_outerwall, tex_floor, tex_ceiling,
|
|
tex_doorslope, tex_windowslope, tex_arc, tex_balconslope, tex_niche: string;
|
|
FScaleDelta: Double;
|
|
FSingleRoom: Boolean;
|
|
|
|
|
|
|
|
implementation
|
|
uses U_BaseCommon, U_ArchCommon, U_Common, U_Protection, U_ProtectionCommon, Form3d;
|
|
|
|
function CoordsCMP(p1, p2: TDoublePoint): Boolean;
|
|
begin
|
|
try
|
|
result := (abs(p1.x - p2.x) < 0.1) and (abs(p1.y - p2.y) < 0.1);
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('U_Arch3D.CoordsCMP', E.Message);
|
|
end;
|
|
end;
|
|
|
|
function AnglesCMP(a1, a2: Double): Boolean;
|
|
var
|
|
a: double;
|
|
begin
|
|
try
|
|
result := false;
|
|
a := abs(a1 - a2);
|
|
a := StrToFloat_My(FormatFloat('0.00', a));
|
|
while a >= 3.14 do
|
|
begin
|
|
a := a - pi;
|
|
end;
|
|
if a < 0.1 then
|
|
Result := True;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('U_Arch3D.AnglesCMP', E.Message);
|
|
end;
|
|
end;
|
|
|
|
function PointDistCMP(p: TDoublePoint; aNetPath: TNetPath): Boolean;
|
|
begin
|
|
try
|
|
Result := True;
|
|
if GetLineLenght(p, aNetPath.p1^) < 1 then
|
|
Result := false;
|
|
if GetLineLenght(p, aNetPath.p2^) < 1 then
|
|
Result := false;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('U_Arch3D.PointDistCMP', E.Message);
|
|
end;
|
|
end;
|
|
|
|
function GetWallTypeByDoorType(aDoor: TNetDoor): TFaceWallType;
|
|
begin
|
|
try
|
|
Result := fwtNone;
|
|
if aDoor.DoorObjType = dotDoor then
|
|
Result := fwtDoorSlope;
|
|
if aDoor.DoorObjType = dotWindow then
|
|
Result := fwtWindowSlope;
|
|
if aDoor.DoorObjType = dotArc then
|
|
Result := fwtArc;
|
|
if aDoor.DoorObjType = dotBalcony then
|
|
Result := fwtBalconSlope;
|
|
if aDoor.DoorObjType = dotNiche then
|
|
Result := fwtNiche;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('U_Arch3D.GetWallTypeByDoorType', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure GetWallPointsWithSlope(var da1, da2, db1, db2: TDoublePoint; hor_a1, hor_a2, hor_b1, hor_b2: double);
|
|
var
|
|
inner_len, outer_len: double;
|
|
begin
|
|
try
|
|
outer_len := GetLineLenght(da1, da2);
|
|
inner_len := GetLineLenght(db1, db2);
|
|
hor_a1 := hor_a1 / outer_len;
|
|
hor_a2 := hor_a2 / outer_len;
|
|
hor_b1 := hor_b1 / inner_len;
|
|
hor_b2 := hor_b2 / inner_len;
|
|
|
|
da1.x := da1.x + (da1.x - da2.x) * hor_a1;
|
|
da1.y := da1.y + (da1.y - da2.y) * hor_a1;
|
|
da2.x := da2.x + (da2.x - da1.x) * hor_a2;
|
|
da2.y := da2.y + (da2.y - da1.y) * hor_a2;
|
|
|
|
db1.x := db1.x + (db1.x - db2.x) * hor_b1;
|
|
db1.y := db1.y + (db1.y - db2.y) * hor_b1;
|
|
db2.x := db2.x + (db2.x - db1.x) * hor_b2;
|
|
db2.y := db2.y + (db2.y - db1.y) * hor_b2;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('U_Arch3D.GetWallPointsWithSlope', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure GetDoorPointsWithSlope(var c: TDoublePoint; d: TDoublePoint; depth: double);
|
|
var
|
|
d_len: double;
|
|
begin
|
|
try
|
|
d_len := GetLineLenght(c, d);
|
|
depth := depth / d_len;
|
|
c.x := d.x - (d.x - c.x) * depth;
|
|
c.y := d.y - (d.y - c.y) * depth;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('U_Arch3D.GetDoorPointsWithSlope', E.Message);
|
|
end;
|
|
end;
|
|
|
|
function GetImageHash(aFName: string): string;
|
|
var
|
|
Buffer: PByte;
|
|
Size: Integer;
|
|
ImageStream: TFileStream;
|
|
begin
|
|
ImageStream := TFileStream.Create(aFName, fmOpenRead);
|
|
try
|
|
size := ImageStream.Size;
|
|
GetMem(Buffer, Size + 1);
|
|
ImageStream.Position := 0;
|
|
ImageStream.Read(Buffer^, Size);
|
|
Result := BuildBuffHash(Buffer, Size);
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('U_Arch3D.GetImageHash', E.Message);
|
|
end;
|
|
FreeMem(Buffer, size);
|
|
FreeAndNil(ImageStream);
|
|
end;
|
|
|
|
|
|
{ T3DModel }
|
|
|
|
constructor T3DModel.Create;
|
|
var
|
|
HashStr, tmpdir, tex_from, tex_to: string;
|
|
begin
|
|
try
|
|
inherited Create;
|
|
FClassName := 'T3DModel';
|
|
FScaleDelta := UOMToMetre(1000 / GCadForm.PCad.MapScale);
|
|
FRooms := TList.Create;
|
|
FName := cModel;
|
|
|
|
FHashs := TStringList.Create;
|
|
tmpdir := ExtractDirByCategoryType(dctPictures);
|
|
|
|
tex_from := ExeDir + '\3DTextures\inner_wall.bmp';
|
|
HashStr := GetImageHash(tex_from);
|
|
tex_to := tmpdir + '\' + HashStr + '.bmp';
|
|
CopyFile(PChar(tex_from), PChar(tex_to), True);
|
|
FHashs.Add(HashStr);
|
|
|
|
tex_from := ExeDir + '\3DTextures\outer_wall.bmp';
|
|
HashStr := GetImageHash(tex_from);
|
|
tex_to := tmpdir + '\' + HashStr + '.bmp';
|
|
CopyFile(PChar(tex_from), PChar(tex_to), True);
|
|
FHashs.Add(HashStr);
|
|
|
|
tex_from := ExeDir + '\3DTextures\floor.bmp';
|
|
HashStr := GetImageHash(tex_from);
|
|
tex_to := tmpdir + '\' + HashStr + '.bmp';
|
|
CopyFile(PChar(tex_from), PChar(tex_to), True);
|
|
FHashs.Add(HashStr);
|
|
|
|
tex_from := ExeDir + '\3DTextures\ceiling.bmp';
|
|
HashStr := GetImageHash(tex_from);
|
|
tex_to := tmpdir + '\' + HashStr + '.bmp';
|
|
CopyFile(PChar(tex_from), PChar(tex_to), True);
|
|
FHashs.Add(HashStr);
|
|
|
|
tex_from := ExeDir + '\3DTextures\door_slope.bmp';
|
|
HashStr := GetImageHash(tex_from);
|
|
tex_to := tmpdir + '\' + HashStr + '.bmp';
|
|
CopyFile(PChar(tex_from), PChar(tex_to), True);
|
|
FHashs.Add(HashStr);
|
|
|
|
tex_from := ExeDir + '\3DTextures\window_slope.bmp';
|
|
HashStr := GetImageHash(tex_from);
|
|
tex_to := tmpdir + '\' + HashStr + '.bmp';
|
|
CopyFile(PChar(tex_from), PChar(tex_to), True);
|
|
FHashs.Add(HashStr);
|
|
|
|
tex_from := ExeDir + '\3DTextures\arc.bmp';
|
|
HashStr := GetImageHash(tex_from);
|
|
tex_to := tmpdir + '\' + HashStr + '.bmp';
|
|
CopyFile(PChar(tex_from), PChar(tex_to), True);
|
|
FHashs.Add(HashStr);
|
|
|
|
tex_from := ExeDir + '\3DTextures\balcon_slope.bmp';
|
|
HashStr := GetImageHash(tex_from);
|
|
tex_to := tmpdir + '\' + HashStr + '.bmp';
|
|
CopyFile(PChar(tex_from), PChar(tex_to), True);
|
|
FHashs.Add(HashStr);
|
|
|
|
tex_from := ExeDir + '\3DTextures\niche.bmp';
|
|
HashStr := GetImageHash(tex_from);
|
|
tex_to := tmpdir + '\' + HashStr + '.bmp';
|
|
CopyFile(PChar(tex_from), PChar(tex_to), True);
|
|
FHashs.Add(HashStr);
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DModel.Create', E.Message);
|
|
end;
|
|
end;
|
|
|
|
function T3DModel.GetObjectBySCSCompon(ASCSCompon: TSCSComponent): TObject;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := nil;
|
|
for i := 0 to FRooms.Count - 1 do
|
|
begin
|
|
Result := T3DRoom(FRooms[i]).GetObjectBySCSCompon(ASCSCompon);
|
|
if Result <> nil then
|
|
Break; //// BREAK ////
|
|
end;
|
|
end;
|
|
|
|
procedure T3DModel.ReadFromStream(Stream: TStream);
|
|
var
|
|
isOk: Boolean;
|
|
xCode, xSize: Integer;
|
|
i, j, intVal: Integer;
|
|
byteVal: Byte;
|
|
wordVal: Word;
|
|
strVal: string;
|
|
dblval: Double;
|
|
xByte: pByte;
|
|
CanAdd: Boolean;
|
|
begin
|
|
try
|
|
isOk := False;
|
|
FName := ReadStringFromStream(Stream);
|
|
repeat
|
|
xCode := 0;
|
|
Stream.Read(xCode, 1);
|
|
if (xCode >= 20) and (xCode < 90) then
|
|
begin
|
|
Stream.Read(intVal, 4);
|
|
end
|
|
else
|
|
if (xCode >= 90) and (xCode < 120) then
|
|
begin
|
|
Stream.Read(byteVal, 1);
|
|
end
|
|
else
|
|
if (xCode >= 120) and (xCode < 150) then
|
|
begin
|
|
Stream.Read(wordVal, 2);
|
|
end
|
|
else
|
|
if (xCode >= 150) and (xCode < 180) then
|
|
begin
|
|
Stream.Read(xSize, 4);
|
|
end
|
|
else
|
|
if (xCode >= 180) and (xCode < 220) then
|
|
begin
|
|
strval := ReadStringFromStream(Stream);
|
|
case xCode of
|
|
180: isOk := true;
|
|
end;
|
|
if (xCode >= 181) and (xCode <= 219) then
|
|
begin
|
|
CanAdd := True;
|
|
for j := 0 to FHashs.Count - 1 do
|
|
begin
|
|
if FHashs[j] = StrVal then
|
|
CanAdd := False;
|
|
end;
|
|
if CanAdd then
|
|
FHashs.Add(strVal);
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 220) and (xCode < 240) then
|
|
begin
|
|
Stream.Read(dblval, 8);
|
|
end;
|
|
until isOk;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DModel.ReadFromStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DModel.SetRelations;
|
|
begin
|
|
try
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DModel.SetRelations', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DModel.WriteToStream(Stream: TStream);
|
|
var
|
|
i: integer;
|
|
xStr: string;
|
|
begin
|
|
try
|
|
WriteString(Stream, FClassName);
|
|
WriteString(Stream, FName);
|
|
for i := 0 to FHashs.Count - 1 do
|
|
begin
|
|
xStr := FHashs[i];
|
|
if ((181 + i) <= 219) then
|
|
WriteStrField(181 + i, Stream, xStr);
|
|
end;
|
|
WriteStrField(180, Stream, 'BaseEnd');
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DModel.WriteToStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
{ T3DRoom }
|
|
|
|
procedure T3DRoom.CollectCeiling(aFaces: TList);
|
|
var
|
|
i, j: integer;
|
|
a3DPointArr: T3DPointArray;
|
|
aFace: TFaceRecord;
|
|
Cnt: Integer;
|
|
xSide: T3DSide;
|
|
begin
|
|
try
|
|
xSide := T3DSide.Create(ftNetCeiling, fwtNone, wstNone, self);
|
|
Cnt := Length(FCeilingConture);
|
|
SetLength(xSide.FPoints, Cnt{ * 2});
|
|
SetLength(xSide.FGLPoints, Cnt{ * 2});
|
|
for i := 0 to Cnt - 1 do
|
|
begin
|
|
xSide.FPoints[i] := FCeilingConture[i];
|
|
end;
|
|
aFace := TFaceRecord.Create(xSide.FPoints, xSide.FColor, ftNetCeiling, 1, False, nil);
|
|
aFaces.Add(aFace);
|
|
xSide.FFace := aFace;
|
|
xSide.FName := cCeiling;
|
|
FCeiling := xSide;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('U_Arch3D.CollectCeiling', E.Message);
|
|
end;
|
|
end;
|
|
|
|
function T3DRoom.GetObjectBySCSCompon(ASCSCompon: TSCSComponent): TObject;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := nil;
|
|
if ASCSCompon = FSCSCompon then
|
|
Result := self;
|
|
//else
|
|
//for i := 0 to FWalls.Count - 1 do
|
|
//begin
|
|
// Result := T3DWall(FRooms[i]).GetObjectBySCSCompon(ASCSCompon);
|
|
// if Result <> nil then
|
|
// Break; //// BREAK ////
|
|
//end;
|
|
end;
|
|
|
|
procedure T3DRoom.CollectFloor(aFaces: TList);
|
|
var
|
|
i, j: integer;
|
|
a3DPointArr: T3DPointArray;
|
|
aFace: TFaceRecord;
|
|
Cnt: Integer;
|
|
xSide: T3DSide;
|
|
begin
|
|
try
|
|
xSide := T3DSide.Create(ftNetFloor, fwtNone, wstNone, Self);
|
|
Cnt := Length(FFloorConture);
|
|
SetLength(xSide.FPoints, Cnt{ * 2});
|
|
SetLength(xSide.FGLPoints, Cnt{ * 2});
|
|
for i := 0 to Cnt - 1 do
|
|
begin
|
|
xSide.FPoints[i] := FFloorConture[i];
|
|
end;
|
|
aFace := TFaceRecord.Create(xSide.FPoints, xSide.FColor, ftNetFloor, 1, False, nil);
|
|
aFaces.Add(aFace);
|
|
xSide.FFace := aFace;
|
|
xSide.FName := cFloor;
|
|
FFloor := xSide;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DRoom.CollectFloor', E.Message);
|
|
end;
|
|
end;
|
|
|
|
{TODO}
|
|
{
|
|
procedure T3DRoom.CollectRoom(aFaces: TList);
|
|
var
|
|
xNetPath: TNetPath;
|
|
i, j, k: integer;
|
|
WallComponID: Integer;
|
|
Room: TSCSComponent;
|
|
SCSCompon: TSCSComponent;
|
|
xWall: T3DWall;
|
|
begin
|
|
try
|
|
Room := GCurrentRoom3DView;
|
|
|
|
if Room = nil then
|
|
begin
|
|
FSingleRoom := False;
|
|
for i := 0 to FPlanObject.Paths.Count - 1 do
|
|
begin
|
|
xNetPath := TNetPath(FPlanObject.Paths[i]);
|
|
xWall := T3DWall.Create(aFaces, xNetPath, Self);
|
|
FWalls.Add(xWall);
|
|
end;
|
|
CollectFloor(aFaces);
|
|
CollectCeiling(aFaces);
|
|
end
|
|
else
|
|
begin
|
|
if Room.ID = FSCSComponID then
|
|
begin
|
|
FSingleRoom := True;
|
|
for i := 0 to FPlanObject.Paths.Count - 1 do
|
|
begin
|
|
xNetPath := TNetPath(FPlanObject.Paths[i]);
|
|
xWall := T3DWall.Create(aFaces, xNetPath, Self);
|
|
FWalls.Add(xWall);
|
|
end;
|
|
CollectFloor(aFaces);
|
|
CollectCeiling(aFaces);
|
|
end;
|
|
end;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DRoom.CollectRoom', E.Message);
|
|
end;
|
|
end;
|
|
}
|
|
|
|
// MARK
|
|
procedure T3DRoom.CollectRoom(aFaces: TList);
|
|
var
|
|
xNetPath: TNetPath;
|
|
i, j, k: integer;
|
|
WallComponID: Integer;
|
|
Room: TSCSComponent;
|
|
SCSCompon: TSCSComponent;
|
|
xWall: T3DWall;
|
|
begin
|
|
try
|
|
//Room := GCurrentRoom3DView;
|
|
|
|
//if Room = nil then
|
|
begin
|
|
//FSingleRoom := False;
|
|
for i := 0 to FPlanObject.Paths.Count - 1 do
|
|
begin
|
|
xNetPath := TNetPath(FPlanObject.Paths[i]);
|
|
xWall := T3DWall.Create(aFaces, xNetPath, Self);
|
|
FWalls.Add(xWall);
|
|
end;
|
|
CollectFloor(aFaces);
|
|
CollectCeiling(aFaces);
|
|
end;
|
|
{
|
|
else
|
|
begin
|
|
if Room.ID = FSCSComponID then
|
|
begin
|
|
FSingleRoom := True;
|
|
for i := 0 to FPlanObject.Paths.Count - 1 do
|
|
begin
|
|
xNetPath := TNetPath(FPlanObject.Paths[i]);
|
|
xWall := T3DWall.Create(aFaces, xNetPath, Self);
|
|
FWalls.Add(xWall);
|
|
end;
|
|
CollectFloor(aFaces);
|
|
CollectCeiling(aFaces);
|
|
end;
|
|
end;
|
|
}
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DRoom.CollectRoom', E.Message);
|
|
end;
|
|
end;
|
|
|
|
{TODO}
|
|
{
|
|
constructor T3DRoom.Create(aFaces: TList; aNet: TNet; aParent: T3DModel);
|
|
begin
|
|
try
|
|
inherited Create;
|
|
FClassName := 'T3DRoom';
|
|
FPlanObject := aNet;
|
|
if aNet <> nil then
|
|
begin
|
|
FSCSCompon := GetArchObjByCADObj(aNet);
|
|
FSCSComponID := FSCSCompon.ID;
|
|
FName := FSCSCompon.Name + ' ' + FSCSCompon.NameMark;
|
|
FNetConture := aNet.GetRoomConture;
|
|
FFloorConture := aNet.GetFloorConture;
|
|
FCeilingConture := aNet.GetCeilingConture;
|
|
end;
|
|
FWalls := TList.Create;
|
|
F3DSObjects := TList.Create;
|
|
FParent := aParent;
|
|
if aFaces <> nil then
|
|
CollectRoom(aFaces);
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DRoom.Create', E.Message);
|
|
end;
|
|
end;
|
|
}
|
|
|
|
// MARK
|
|
constructor T3DRoom.Create(aFaces: TList; aNet: TNet; aParent: T3DModel);
|
|
begin
|
|
try
|
|
inherited Create;
|
|
FClassName := 'T3DRoom';
|
|
FPlanObject := aNet;
|
|
if aNet <> nil then
|
|
begin
|
|
FSCSCompon := GetArchObjByCADObj(aNet);
|
|
FSCSComponID := FSCSCompon.ID;
|
|
FName := FSCSCompon.Name + ' ' + FSCSCompon.NameMark;
|
|
FNetConture := aNet.GetRoomConture;
|
|
FFloorConture := aNet.GetFloorConture;
|
|
FCeilingConture := aNet.GetCeilingConture;
|
|
end;
|
|
FWalls := TList.Create;
|
|
F3DSObjects := TList.Create;
|
|
FParent := aParent;
|
|
|
|
FVisible := True;
|
|
if aFaces <> nil then
|
|
begin
|
|
if GCurrentRoom3DView = nil then
|
|
begin
|
|
FSingleRoom := False;
|
|
CollectRoom(aFaces);
|
|
end
|
|
else
|
|
begin
|
|
FSingleRoom := True;
|
|
if FSCSComponID = GCurrentRoom3DView.ID then
|
|
CollectRoom(aFaces)
|
|
else
|
|
FVisible := False;
|
|
end;
|
|
end;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DRoom.Create', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DRoom.ReadFromStream(Stream: TStream);
|
|
var
|
|
isOk: Boolean;
|
|
xCode, xSize: Integer;
|
|
intVal: Integer;
|
|
byteVal: Byte;
|
|
wordVal: Word;
|
|
strVal: string;
|
|
dblval: Double;
|
|
xByte: pByte;
|
|
begin
|
|
try
|
|
isOk := False;
|
|
FName := ReadStringFromStream(Stream);
|
|
repeat
|
|
xCode := 0;
|
|
Stream.Read(xCode, 1);
|
|
if (xCode >= 20) and (xCode < 90) then
|
|
begin
|
|
Stream.Read(intVal, 4);
|
|
Case xcode of
|
|
20: FParentIndex := IntVal;
|
|
21: FSCSComponID := intVal;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 90) and (xCode < 120) then
|
|
begin
|
|
Stream.Read(byteVal, 1);
|
|
case xCode of
|
|
90: begin
|
|
if byteVal = 0 then
|
|
FVisible := False
|
|
else
|
|
FVisible := True;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 120) and (xCode < 150) then
|
|
begin
|
|
Stream.Read(wordVal, 2);
|
|
end
|
|
else
|
|
if (xCode >= 150) and (xCode < 180) then
|
|
begin
|
|
Stream.Read(xSize, 4);
|
|
end
|
|
else
|
|
if (xCode >= 180) and (xCode < 220) then
|
|
begin
|
|
strval := ReadStringFromStream(Stream);
|
|
case xCode of
|
|
180: isOk := true;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 220) and (xCode < 240) then
|
|
begin
|
|
Stream.Read(dblval, 8);
|
|
end;
|
|
until isOk;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DRoom.ReadFromStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DRoom.SetRelations;
|
|
begin
|
|
try
|
|
if FParentIndex = - 1 then
|
|
begin
|
|
FParent := nil;
|
|
end
|
|
else
|
|
begin
|
|
FParent := T3DModel(ModelObjectsList.Items[FParentIndex]);
|
|
T3DModel(FParent).FRooms.Add(self);
|
|
end;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DRoom.SetRelations', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DRoom.WriteToStream(Stream: TStream);
|
|
var
|
|
xInt: Integer;
|
|
xByte: Byte;
|
|
begin
|
|
try
|
|
WriteString(Stream, FClassName);
|
|
WriteString(Stream, FName);
|
|
xInt := ModelObjectsList.IndexOf(FParent);
|
|
WriteField(20, Stream, xInt, sizeof(xInt));
|
|
xInt := FSCSComponID;
|
|
WriteField(21, Stream, xInt, sizeof(xInt));
|
|
if FVisible then
|
|
xByte := 1
|
|
else
|
|
xByte := 0;
|
|
WriteField(90, Stream, xByte, sizeof(xByte));
|
|
WriteStrField(180, Stream, 'BaseEnd');
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DRoom.WriteToStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
{ T3DSide }
|
|
|
|
procedure T3DSide.CollectWallElementSide(aFaces: TList; ap: T3DPointArray; fTrans: boolean = False);
|
|
var
|
|
aFace: TFaceRecord;
|
|
begin
|
|
try
|
|
SetLength(FPoints, 4);
|
|
SetLength(FGLPoints, 4);
|
|
FPoints[0] := ap[0];
|
|
FPoints[1] := ap[1];
|
|
FPoints[2] := ap[2];
|
|
FPoints[3] := ap[3];
|
|
aFace := TFaceRecord.Create(FPoints, clGray, FFaceType, 1, fTrans, nil);
|
|
aFace.FFaceWallType := FWallType;
|
|
aFace.FWallSideType := FSideType;
|
|
aFaces.Add(aFace);
|
|
FFace := aFace;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DSide.CollectWallElementSide', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DSide.CollectWallSide(aFaces: TList; ap: T3DPointArray);
|
|
var
|
|
aFace: TFaceRecord;
|
|
begin
|
|
try
|
|
SetLength(FPoints, 4);
|
|
SetLength(FGLPoints, 4);
|
|
FPoints[0] := ap[0];
|
|
FPoints[1] := ap[1];
|
|
FPoints[2] := ap[3];
|
|
FPoints[3] := ap[2];
|
|
aFace := TFaceRecord.Create(FPoints, clGray, FFaceType, 1, False, nil);
|
|
aFace.FFaceWallType := FWallType;
|
|
aFace.FWallSideType := FSideType;
|
|
aFaces.Add(aFace);
|
|
FFace := aFace;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DSide.CollectWallSide', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DSide.CollectArcWallSide(aFaces: TList; ap: T3DPointArray);
|
|
var
|
|
i: integer;
|
|
j: integer;
|
|
aFace: TFaceRecord;
|
|
aFPoints: T3DPointArray;
|
|
begin
|
|
try
|
|
SetLength(aFPoints, 4);
|
|
|
|
|
|
if (FSideType = wstUpper) or (FSideType = wstUnder) then
|
|
begin
|
|
SetLength(FPoints, Length(ap));
|
|
SetLength(FGLPoints, Length(ap));
|
|
for i := 0 to Length(ap) - 1 do
|
|
FPoints[i] := ap[i];
|
|
|
|
aFace := TFaceRecord.Create(FPoints, clGray, FFaceType, 1, False, nil);
|
|
aFace.FFaceWallType := FWallType;
|
|
aFace.FWallSideType := FSideType;
|
|
aFaces.Add(aFace);
|
|
FFace := aFace;
|
|
FAsArc := True;
|
|
end
|
|
else
|
|
begin
|
|
SetLength(FPoints, 4);
|
|
SetLength(FGLPoints, 4);
|
|
|
|
j := 0;
|
|
while j + 1 < (Length(ap) div 2) do
|
|
begin
|
|
aFPoints[0] := ap[j];
|
|
aFPoints[1] := ap[j + 1];
|
|
//aFPoints[2] := ap[Length(ap) - j - 2];
|
|
//aFPoints[3] := ap[Length(ap) - j - 1];
|
|
|
|
aFPoints[2] := ap[(Length(ap) div 2) + 1 + j];
|
|
aFPoints[3] := ap[(Length(ap) div 2) + j];
|
|
|
|
//aFPoints[2] := ap[j + 2];
|
|
//aFPoints[3] := ap[j + 3];
|
|
|
|
if j = 0 then
|
|
begin
|
|
FPoints[0] := aFPoints[0];
|
|
FPoints[1] := aFPoints[1];
|
|
FPoints[2] := aFPoints[2];
|
|
FPoints[3] := aFPoints[3];
|
|
end;
|
|
|
|
aFace := TFaceRecord.Create(aFPoints, clGray, FFaceType, 1, False, nil);
|
|
aFace.FFaceWallType := FWallType;
|
|
aFace.FWallSideType := FSideType;
|
|
aFaces.Add(aFace);
|
|
if j = 0 then
|
|
FFace := aFace;
|
|
FAsArc := True;
|
|
j := j + 1;
|
|
end;
|
|
end;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DSide.CollectWallSide', E.Message);
|
|
end;
|
|
end;
|
|
|
|
|
|
constructor T3DSide.Create(aFaceType: TFaceType; aWallType: TFaceWallType; aSideType: TWallSideType; aParent: TObject);
|
|
begin
|
|
try
|
|
inherited Create;
|
|
FClassName := 'T3DSide';
|
|
FColor := clGray;
|
|
FFaceType := aFaceType;
|
|
FWallType := aWallType;
|
|
FSideType := aSideType;
|
|
FParent := aParent;
|
|
FGLObject := nil;
|
|
FFace := nil;
|
|
FDescription := TStringList.Create;
|
|
FRotate := 0;
|
|
FMirror := False;
|
|
FAsArc := False;
|
|
FTextureHash := '';
|
|
FTexture_ext := '';
|
|
FSubSides := TList.Create;
|
|
if FParent <> nil then
|
|
begin
|
|
if FParent is T3DWall then
|
|
begin
|
|
FName := cSide + ' ' + IntToStr(T3DWall(FParent).FSides.Count + 1);
|
|
end;
|
|
if FParent is T3DWallElement then
|
|
begin
|
|
FName := cSide + ' ' + IntToStr(T3DWallElement(FParent).FSides.Count + 1);
|
|
end;
|
|
if FParent is T3DBalconElement then
|
|
begin
|
|
FName := cSide + ' ' + IntToStr(T3DBalconElement(FParent).FSides.Count + 1);
|
|
end;
|
|
if FParent is T3DSlope then
|
|
begin
|
|
FName := cSide + ' ' + IntToStr(T3DSlope(FParent).FSides.Count + 1);
|
|
end;
|
|
if FParent is T3DSide then
|
|
begin
|
|
FName := cSubSide + ' ' + IntToStr(T3DSide(FParent).FSubSides.Count + 1);
|
|
end;
|
|
|
|
end;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DSide.Create', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DSide.ReadFromStream(Stream: TStream);
|
|
var
|
|
isOk: Boolean;
|
|
i, xCode, xSize: Integer;
|
|
intVal: Integer;
|
|
byteVal: Byte;
|
|
wordVal: Word;
|
|
strVal: string;
|
|
dblval: Double;
|
|
xByte: pByte;
|
|
xd, yd, zd: Double;
|
|
pCnt: Integer;
|
|
|
|
begin
|
|
try
|
|
isOk := False;
|
|
FName := ReadStringFromStream(Stream);
|
|
repeat
|
|
xCode := 0;
|
|
Stream.Read(xCode, 1);
|
|
if (xCode >= 20) and (xCode < 90) then
|
|
begin
|
|
Stream.Read(intVal, 4);
|
|
Case xCode of
|
|
20: FParentIndex := IntVal;
|
|
21: FFaceType := TFaceType(IntVal);
|
|
22: FWallType := TFaceWallType(IntVal);
|
|
23: FSideType := TWallSideType(IntVal);
|
|
24: FColor := IntVal;
|
|
25: FRotate := IntVal;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 90) and (xCode < 120) then
|
|
begin
|
|
Stream.Read(byteVal, 1);
|
|
case xCode of
|
|
90: begin
|
|
if byteVal = 0 then
|
|
FMirror := False
|
|
else
|
|
FMirror := True;
|
|
end;
|
|
91: begin
|
|
if byteVal = 0 then
|
|
FAsArc := False
|
|
else
|
|
FAsArc := True;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 120) and (xCode < 150) then
|
|
begin
|
|
Stream.Read(wordVal, 2);
|
|
end
|
|
else
|
|
if (xCode >= 150) and (xCode < 180) then
|
|
begin
|
|
Stream.Read(xSize, 4);
|
|
Case xcode of
|
|
150: begin
|
|
pCnt := xSize div 24;
|
|
SetLength(FPoints, pCnt);
|
|
for i := 0 to pCnt - 1 do
|
|
begin
|
|
Stream.read(xd, 8);
|
|
Stream.read(yd, 8);
|
|
Stream.read(zd, 8);
|
|
FPoints[i].x := xd;
|
|
FPoints[i].y := yd;
|
|
FPoints[i].z := zd;
|
|
end;
|
|
end;
|
|
151: begin
|
|
pCnt := xSize div 24;
|
|
SetLength(FGLPoints, pCnt);
|
|
for i := 0 to pCnt - 1 do
|
|
begin
|
|
Stream.read(xd, 8);
|
|
Stream.read(yd, 8);
|
|
Stream.read(zd, 8);
|
|
FGLPoints[i].x := xd;
|
|
FGLPoints[i].y := yd;
|
|
FGLPoints[i].z := zd;
|
|
end;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 180) and (xCode < 220) then
|
|
begin
|
|
strVal := ReadStringFromStream(Stream);
|
|
case xCode of
|
|
180: isOk := true;
|
|
181: FDescription.Text := strVal;
|
|
182: FTextureHash := strVal;
|
|
183: FTexture_ext := strVal;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 220) and (xCode < 240) then
|
|
begin
|
|
Stream.Read(dblval, 8);
|
|
end;
|
|
until isOk;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DSide.ReadFromStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DSide.SetRelations;
|
|
begin
|
|
try
|
|
if FParentIndex = - 1 then
|
|
begin
|
|
FParent := nil;
|
|
end
|
|
else
|
|
begin
|
|
FParent := TObject(ModelObjectsList.Items[FParentIndex]);
|
|
if FParent is T3DRoom then
|
|
begin
|
|
if FFaceType = ftNetCeiling then
|
|
T3DRoom(FParent).FCeiling := self;
|
|
if FFaceType = ftNetFloor then
|
|
T3DRoom(FParent).FFloor := self;
|
|
end;
|
|
if FParent is T3DWall then
|
|
begin
|
|
T3DWall(FParent).FSides.Add(self);
|
|
end;
|
|
if FParent is T3DWallElement then
|
|
begin
|
|
T3DWallElement(FParent).FSides.Add(self);
|
|
end;
|
|
if FParent is T3DBalconElement then
|
|
begin
|
|
T3DBalconElement(FParent).FSides.Add(self);
|
|
end;
|
|
if FParent is T3DSlope then
|
|
begin
|
|
T3DSlope(FParent).FSides.Add(self);
|
|
end;
|
|
if FParent is T3DSide then
|
|
begin
|
|
T3DSide(FParent).FSubSides.Add(self);
|
|
end;
|
|
|
|
end;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DSide.SetRelations', E.Message);
|
|
end;
|
|
end;
|
|
|
|
function T3DSide.GetArea: Double;
|
|
var
|
|
PointCnt: Integer;
|
|
begin
|
|
Result := 0;
|
|
PointCnt := Length(Self.FPoints);
|
|
if PointCnt = 4 then
|
|
Result := GetTriangleArea3D(Self.FPoints[0], Self.FPoints[1], Self.FPoints[2])+
|
|
GetTriangleArea3D(Self.FPoints[2], Self.FPoints[3], Self.FPoints[0]);
|
|
end;
|
|
|
|
procedure T3DSide.WriteToStream(Stream: TStream);
|
|
var
|
|
i, xCount, xInt: Integer;
|
|
xByte: Byte;
|
|
xStr: string;
|
|
xDouble: Double;
|
|
aPoints, bPoints: pInt;
|
|
|
|
begin
|
|
try
|
|
WriteString(Stream, FClassName);
|
|
WriteString(Stream, FName);
|
|
xInt := ModelObjectsList.IndexOf(FParent);
|
|
WriteField(20, Stream, xInt, sizeof(xInt));
|
|
|
|
xInt := Ord(FFaceType);
|
|
WriteField(21, Stream, xInt, sizeof(xInt));
|
|
|
|
xInt := Ord(FWallType);
|
|
WriteField(22, Stream, xInt, sizeof(xInt));
|
|
|
|
xInt := Ord(FSideType);
|
|
WriteField(23, Stream, xInt, sizeof(xInt));
|
|
|
|
xInt := FColor;
|
|
WriteField(24, Stream, xInt, sizeof(xInt));
|
|
|
|
xInt := FRotate;
|
|
WriteField(25, Stream, xInt, sizeof(xInt));
|
|
|
|
if FMirror then
|
|
xByte := 1
|
|
else
|
|
xByte := 0;
|
|
WriteField(90, Stream, xByte, sizeof(xByte));
|
|
|
|
if FAsArc then
|
|
xByte := 1
|
|
else
|
|
xByte := 0;
|
|
WriteField(91, Stream, xByte, sizeof(xByte));
|
|
|
|
xCount := Length(FPoints);
|
|
GetMem(aPoints, xCount * 24);
|
|
for i := 0 to xCount - 1 do
|
|
begin
|
|
pDouble(pChar(aPoints) + (i * 24) + 0)^ := FPoints[i].x;
|
|
pDouble(pChar(aPoints) + (i * 24) + 8)^ := FPoints[i].y;
|
|
pDouble(pChar(aPoints) + (i * 24) + 16)^ := FPoints[i].z;
|
|
end;
|
|
WriteBinField(150, Stream, pByte(aPoints), xCount * 24);
|
|
FreeMem(aPoints, xCount * 24);
|
|
|
|
xCount := Length(FGLPoints);
|
|
GetMem(aPoints, xCount * 24);
|
|
for i := 0 to xCount - 1 do
|
|
begin
|
|
pDouble(pChar(aPoints) + (i * 24) + 0)^ := FGLPoints[i].x;
|
|
pDouble(pChar(aPoints) + (i * 24) + 8)^ := FGLPoints[i].y;
|
|
pDouble(pChar(aPoints) + (i * 24) + 16)^ := FGLPoints[i].z;
|
|
end;
|
|
WriteBinField(151, Stream, pByte(aPoints), xCount * 24);
|
|
FreeMem(aPoints, xCount * 24);
|
|
|
|
WriteStrField(181, Stream, FDescription.Text);
|
|
WriteStrField(182, Stream, FTextureHash);
|
|
WriteStrField(183, Stream, FTexture_ext);
|
|
WriteStrField(180, Stream, 'BaseEnd');
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DSide.WriteToStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
{ T3DWall }
|
|
|
|
function T3DWall.CalcPointHeight(p1, p2, Point: TDoublePoint; p1h, p2h: Double): Double;
|
|
var
|
|
x, y: Double;
|
|
p: TDoublePoint;
|
|
begin
|
|
try
|
|
Result := 0;
|
|
// Êîîðäèíàòó Ó áóäåì ðàññìàòðèâàòü êàê Z
|
|
// ÷òîáû íîðìàëèçèðîâàòü Y (òîåñòü äëÿ p1, p2 áûë îäèíàêîâûé), áóäåì ñ÷èòàòü îò íîëÿ, ñ÷èòàÿ îñòàïëüíûå êîîðäèíàòû ïî äëèíàì
|
|
x := GetLineLenght(p1, Point);
|
|
y := 1;
|
|
p := LineIntersect(DoublePoint(0, p1h), DoublePoint(GetLineLenght(p1, p2), p2h), DoublePoint(x,0), DoublePoint(x,1000));
|
|
x := GetLineLenght(p1, Point)+1;
|
|
PointToLine(DoublePoint(1, p1h+1), DoublePoint(GetLineLenght(p1, p2)+1, p2h+1), x, y);
|
|
Result := y;
|
|
Result := p.y;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWall.CalcPointHeight', E.Message);
|
|
end;
|
|
end;
|
|
|
|
function T3DWall.CheckAdjoiningWallSide(l1, l2: TDoublePoint): Boolean;
|
|
var
|
|
i, j: integer;
|
|
CAD: TF_CAD;
|
|
Nets: TList;
|
|
Net: TNet;
|
|
NetInnerConture, NetOuterConture: TDoublePointArr;
|
|
mp: TDoublePoint;
|
|
len, len_a, len_b: double;
|
|
xl1, xl2: TDoublePoint;
|
|
begin
|
|
try
|
|
Result := False;
|
|
CAD := TF_CAD(TPowerCad(FPlanObject.Net.Owner).Owner);
|
|
Nets := GetAllOtherNetsFromCAD(CAD, FPlanObject.Net);
|
|
mp.x := (l1.x + l2.x) / 2;
|
|
mp.y := (l1.y + l2.y) / 2;
|
|
|
|
len_a := 1;
|
|
len_b := GetLineLenght(l1, l2);
|
|
len := len_a / len_b;
|
|
xl1.x := l2.x - (l2.x - l1.x) * len;
|
|
xl1.y := l2.y - (l2.y - l1.y) * len;
|
|
xl2.x := l1.x - (l1.x - l2.x) * len;
|
|
xl2.y := l1.y - (l1.y - l2.y) * len;
|
|
|
|
// Ïåðåáèðàåì âñå äðóãèå êîìíàòû è ñìîòðèì ïîïàäàþò ëè îáå òî÷êè âî âíåøíèé êîíòóð êîìíàòû
|
|
// åñëè äà, òî îíà ÷àñòü ñòåíû ñìåæíàÿ è åé ñòàòóñ - âíóòðåííÿ
|
|
for i := 0 to Nets.Count - 1 do
|
|
begin
|
|
Net := TNet(Nets[i]);
|
|
// çàäàåì êîíòóð ñòåíû
|
|
NetInnerConture := Net.GetRoomInnerConture;
|
|
NetOuterConture := Net.GetRoomOuterConture;
|
|
if (PtInPolygon(NetOuterConture, xl1) and PtInPolygon(NetOuterConture, xl2)) or
|
|
(PtInPolygon(NetInnerConture, xl1) and PtInPolygon(NetInnerConture, xl2)) then
|
|
begin
|
|
Result := True;
|
|
exit;
|
|
end;
|
|
end;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWall.CheckAdjoiningWallSide', E.Message);
|
|
end;
|
|
end;
|
|
|
|
function T3DWall.CollectWall(aFaces: TList; ap: T3DPointArray; aAdjoiningList: TList; aWallViewType: TWallViewType): TList;
|
|
var
|
|
i: integer;
|
|
a3DPointArr, a3DPointArrArc: T3DPointArray;
|
|
aFace: TFaceRecord;
|
|
WallSideConture: TDoublePointArr;
|
|
AdjoiningList: TList;
|
|
pp: PDoublePoint;
|
|
p: TDoublePoint;
|
|
l1, l2: TDoublePoint;
|
|
xSide: T3DSide;
|
|
|
|
{
|
|
j: integer;
|
|
a3DPointArrCeil: T3DPointArray;
|
|
aFaceCeil: TFaceRecord;
|
|
Cnt: Integer;
|
|
xSideCeil: T3DSide;
|
|
}
|
|
|
|
begin
|
|
try
|
|
// ïåðåôîìèðîâàòü aAdjoiningList, âûÿâèòü òîëüêî òå òî÷êè êîòîðûå âõîäÿò â ýòîò áëîê ñòåíû
|
|
AdjoiningList := TList.Create;
|
|
for i := 0 to aAdjoiningList.Count - 1 do
|
|
begin
|
|
pp := PDoublePoint(aAdjoiningList[i]);
|
|
p := pp^;
|
|
SetLength(WallSideConture, 4);
|
|
WallSideConture[0] := ap[0];
|
|
WallSideConture[1] := ap[1];
|
|
WallSideConture[2] := ap[3];
|
|
WallSideConture[3] := ap[2];
|
|
if PtInPolygon(WallSideConture, p) then
|
|
AdjoiningList.Add(pp);
|
|
end;
|
|
|
|
Result := TList.Create;
|
|
SetLength(a3DPointArr, 4);
|
|
|
|
// Íèæíÿÿ ãðàíü
|
|
if not (wvtNoUnder in aWallViewType) then
|
|
begin
|
|
a3DPointArr[0] := ap[0];
|
|
a3DPointArr[1] := ap[1];
|
|
a3DPointArr[2] := ap[2];
|
|
a3DPointArr[3] := ap[3];
|
|
|
|
if PtInPolygon(FParent.FNetConture, a3DPointArr[0]) and PtInPolygon(FParent.FNetConture, a3DPointArr[1]) and PtInPolygon(FParent.FNetConture, a3DPointArr[2]) and PtInPolygon(FParent.FNetConture, a3DPointArr[3]) then
|
|
xSide := T3DSide.Create(ftNetPath, fwtInner, wstUnder, self)
|
|
else
|
|
xSide := T3DSide.Create(ftNetPath, fwtOuter, wstUnder, self);
|
|
// new ***
|
|
if FIsArc then
|
|
begin
|
|
a3DPointArrArc := GetArcWallPoints(a3DPointArr);
|
|
xSide.CollectArcWallSide(aFaces, a3DPointArrArc);
|
|
end
|
|
else
|
|
xSide.CollectWallSide(aFaces, a3DPointArr);
|
|
// new ***
|
|
FSides.Add(xSide);
|
|
Result.Add(xSide);
|
|
end;
|
|
|
|
// Âåðõíÿÿ ãðàíü
|
|
if not (wvtNoUpper in aWallViewType) then
|
|
begin
|
|
a3DPointArr[0] := ap[4];
|
|
a3DPointArr[1] := ap[5];
|
|
a3DPointArr[2] := ap[6];
|
|
a3DPointArr[3] := ap[7];
|
|
|
|
if PtInPolygon(FParent.FNetConture, a3DPointArr[0]) and PtInPolygon(FParent.FNetConture, a3DPointArr[1]) and PtInPolygon(FParent.FNetConture, a3DPointArr[2]) and PtInPolygon(FParent.FNetConture, a3DPointArr[3]) then
|
|
xSide := T3DSide.Create(ftNetPath, fwtInner, wstUpper, self)
|
|
else
|
|
xSide := T3DSide.Create(ftNetPath, fwtOuter, wstUpper, self);
|
|
// new ***
|
|
if FIsArc then
|
|
begin
|
|
a3DPointArrArc := GetArcWallPoints(a3DPointArr);
|
|
xSide.CollectArcWallSide(aFaces, a3DPointArrArc);
|
|
|
|
(*
|
|
try
|
|
xSideCeil := T3DSide.Create(ftNetCeiling, fwtNone, wstNone, self);
|
|
Cnt := Length(a3DPointArrArc) div 2;
|
|
SetLength(xSideCeil.FPoints, Cnt{ * 2});
|
|
SetLength(xSideCeil.FGLPoints, Cnt{ * 2});
|
|
for j := 0 to Cnt - 1 do
|
|
begin
|
|
xSideCeil.FPoints[j] := a3DPointArrArc[j];
|
|
end;
|
|
aFaceCeil := TFaceRecord.Create(xSideCeil.FPoints, xSideCeil.FColor, ftNetCeiling, 1, False, nil);
|
|
aFaces.Add(aFaceCeil);
|
|
xSideCeil.FFace := aFaceCeil;
|
|
xSideCeil.FName := cCeiling;
|
|
//FCeiling := xSideCeil;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('U_Arch3D.CollectWall_Ceiling', E.Message);
|
|
end;
|
|
*)
|
|
|
|
end
|
|
else
|
|
xSide.CollectWallSide(aFaces, a3DPointArr);
|
|
// new ***
|
|
FSides.Add(xSide);
|
|
Result.Add(xSide);
|
|
end;
|
|
|
|
// Ëåâàÿ ãðàíü
|
|
if not (wvtNoLeft in aWallViewType) then
|
|
begin
|
|
a3DPointArr[0] := ap[0];
|
|
a3DPointArr[1] := ap[1];
|
|
a3DPointArr[2] := ap[4];
|
|
a3DPointArr[3] := ap[5];
|
|
|
|
if (PtInPolygon(FParent.FNetConture, a3DPointArr[0]) and PtInPolygon(FParent.FNetConture, a3DPointArr[2])) or
|
|
(PtInPolygon(FParent.FNetConture, a3DPointArr[1]) and PtInPolygon(FParent.FNetConture, a3DPointArr[3])) then
|
|
begin
|
|
xSide := T3DSide.Create(ftNetPath, fwtInner, wstLeft, self);
|
|
// new ***
|
|
if FIsArc then
|
|
begin
|
|
a3DPointArrArc := GetArcWallPoints(a3DPointArr, True);
|
|
xSide.CollectArcWallSide(aFaces, a3DPointArrArc);
|
|
end
|
|
else
|
|
xSide.CollectWallSide(aFaces, a3DPointArr);
|
|
// new ***
|
|
FSides.Add(xSide);
|
|
Result.Add(xSide);
|
|
end
|
|
else
|
|
begin
|
|
// íà ýòîé ãðàíè íóæíî ðàçäåëåíèå
|
|
if (AdjoiningList <> nil) and (AdjoiningList.Count > 0) then
|
|
begin
|
|
CollectWallWithAdjoining(aFaces, a3DPointArr, AdjoiningList, wstLeft);
|
|
end
|
|
else
|
|
begin
|
|
l1 := ap[0];
|
|
l2 := ap[1];
|
|
if CheckAdjoiningWallSide(l1, l2) then
|
|
xSide := T3DSide.Create(ftNetPath, fwtInner, wstLeft, self)
|
|
else
|
|
xSide := T3DSide.Create(ftNetPath, fwtOuter, wstLeft, self);
|
|
// new ***
|
|
if FIsArc then
|
|
begin
|
|
a3DPointArrArc := GetArcWallPoints(a3DPointArr, True);
|
|
xSide.CollectArcWallSide(aFaces, a3DPointArrArc);
|
|
end
|
|
else
|
|
xSide.CollectWallSide(aFaces, a3DPointArr);
|
|
// new ***
|
|
FSides.Add(xSide);
|
|
Result.Add(xSide);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
// Ïðàâàÿ ãðàíü
|
|
if not (wvtNoRight in aWallViewType) then
|
|
begin
|
|
a3DPointArr[0] := ap[2];
|
|
a3DPointArr[1] := ap[3];
|
|
a3DPointArr[2] := ap[6];
|
|
a3DPointArr[3] := ap[7];
|
|
|
|
if (PtInPolygon(FParent.FNetConture, a3DPointArr[0]) and PtInPolygon(FParent.FNetConture, a3DPointArr[2])) or
|
|
(PtInPolygon(FParent.FNetConture, a3DPointArr[1]) and PtInPolygon(FParent.FNetConture, a3DPointArr[3])) then
|
|
begin
|
|
xSide := T3DSide.Create(ftNetPath, fwtInner, wstRight, self);
|
|
// new ***
|
|
|
|
if FIsArc then
|
|
begin
|
|
a3DPointArrArc := GetArcWallPoints(a3DPointArr, True);
|
|
xSide.CollectArcWallSide(aFaces, a3DPointArrArc);
|
|
end
|
|
else
|
|
xSide.CollectWallSide(aFaces, a3DPointArr);
|
|
// new ***
|
|
FSides.Add(xSide);
|
|
Result.Add(xSide);
|
|
end
|
|
else
|
|
begin
|
|
// íà ýòîé ãðàíè íóæíî ðàçäåëåíèå
|
|
if (AdjoiningList <> nil) and (AdjoiningList.Count > 0) then
|
|
begin
|
|
CollectWallWithAdjoining(aFaces, a3DPointArr, AdjoiningList, wstRight);
|
|
end
|
|
else
|
|
begin
|
|
l1 := ap[2];
|
|
l2 := ap[3];
|
|
if CheckAdjoiningWallSide(l1, l2) then
|
|
xSide := T3DSide.Create(ftNetPath, fwtInner, wstRight, self)
|
|
else
|
|
xSide := T3DSide.Create(ftNetPath, fwtOuter, wstRight, self);
|
|
// new ***
|
|
if FIsArc then
|
|
begin
|
|
a3DPointArrArc := GetArcWallPoints(a3DPointArr, True);
|
|
xSide.CollectArcWallSide(aFaces, a3DPointArrArc);
|
|
end
|
|
else
|
|
xSide.CollectWallSide(aFaces, a3DPointArr);
|
|
// new ***
|
|
FSides.Add(xSide);
|
|
Result.Add(xSide);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
// Ëåâàÿ Áîêîâàÿ ãðàíü
|
|
if not (wvtNoLeftSide in aWallViewType) then
|
|
begin
|
|
a3DPointArr[0] := ap[0];
|
|
a3DPointArr[1] := ap[4];
|
|
a3DPointArr[2] := ap[2];
|
|
a3DPointArr[3] := ap[6];
|
|
|
|
if PtInPolygon(FParent.FNetConture, a3DPointArr[0]) and PtInPolygon(FParent.FNetConture, a3DPointArr[1]) and PtInPolygon(FParent.FNetConture, a3DPointArr[2]) and PtInPolygon(FParent.FNetConture, a3DPointArr[3]) then
|
|
xSide := T3DSide.Create(ftNetPath, fwtInner, wstLeftSide, self)
|
|
else
|
|
xSide := T3DSide.Create(ftNetPath, fwtOuter, wstLeftSide, self);
|
|
xSide.CollectWallSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
Result.Add(xSide);
|
|
end;
|
|
|
|
// Ïðàâàÿ Áîêîâàÿ ãðàíü
|
|
if not (wvtNoRightSide in aWallViewType) then
|
|
begin
|
|
a3DPointArr[0] := ap[1];
|
|
a3DPointArr[1] := ap[5];
|
|
a3DPointArr[2] := ap[3];
|
|
a3DPointArr[3] := ap[7];
|
|
|
|
if PtInPolygon(FParent.FNetConture, a3DPointArr[0]) and PtInPolygon(FParent.FNetConture, a3DPointArr[1]) and PtInPolygon(FParent.FNetConture, a3DPointArr[2]) and PtInPolygon(FParent.FNetConture, a3DPointArr[3]) then
|
|
xSide := T3DSide.Create(ftNetPath, fwtInner, wstRightSide, self)
|
|
else
|
|
xSide := T3DSide.Create(ftNetPath, fwtOuter, wstRightSide, self);
|
|
xSide.CollectWallSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
Result.Add(xSide);
|
|
end;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWall.CollectWall', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DWall.CollectWallWithAdjoining(aFaces: TList; ap: T3DPointArray; aAdjoiningList: TList; aWallSideType: TWallSideType);
|
|
var
|
|
pp1, pp2: PDoublePoint;
|
|
p1, p2, l1, l2, h1, h2, xl, xh, xl1, xh1: TDoublePoint;
|
|
i, j: integer;
|
|
koef, len1, len2: double;
|
|
WallPoints: TList;
|
|
Inserted: Boolean;
|
|
a3DPointArr: T3DPointArray;
|
|
aFace: TFaceRecord;
|
|
WallSideConture: TDoublePointArr;
|
|
xSide: T3DSide;
|
|
begin
|
|
try
|
|
l1 := ap[0];
|
|
l2 := ap[1];
|
|
h1 := ap[2];
|
|
h2 := ap[3];
|
|
WallPoints := TList.create;
|
|
SetLength(a3DPointArr, 4);
|
|
for i := 0 to aAdjoiningList.Count - 1 do
|
|
begin
|
|
pp1 := PDoublePoint(aAdjoiningList[i]);
|
|
p1 := pp1^;
|
|
// Ïðîâåðèòü, ÷òî òî÷êà âõîäèò èìåííî â ýòó ãðàíü ñòåíû!!!
|
|
begin
|
|
len1 := GetLineLenght(l1, p1);
|
|
Inserted := False;
|
|
// îòñîðòèðîâàòü, ÷òîáû øëè ïî ïîðÿäêó
|
|
for j := 0 to WallPoints.Count - 1 do
|
|
begin
|
|
pp2 := PDoublePoint(WallPoints[j]);
|
|
p2 := pp2^;
|
|
len2 := GetLineLenght(l1, p2);
|
|
if len1 < len2 then
|
|
begin
|
|
WallPoints.Insert(j, pp1);
|
|
Inserted := True;
|
|
break;
|
|
end;
|
|
end;
|
|
if not Inserted then
|
|
WallPoints.Add(pp1);
|
|
end;
|
|
end;
|
|
// ïåðåáèðàåì òî÷êè è ñòðîèì îòðåçêè ñòåíû
|
|
xl1 := l1;
|
|
xh1 := h1;
|
|
for i := 0 to WallPoints.Count - 1 do
|
|
begin
|
|
p1 := PDoublePoint(WallPoints[i])^;
|
|
len1 := GetLineLenght(l1, p1);
|
|
len2 := GetLineLenght(l2, p1);
|
|
koef := len1 / (len1 + len2);
|
|
xl.x := l1.x - (l1.x - l2.x) * koef;
|
|
xl.y := l1.y - (l1.y - l2.y) * koef;
|
|
xl.z := l1.z;
|
|
xh := xl;
|
|
xh.z := h1.z;
|
|
|
|
a3DPointArr[0] := xl1;
|
|
a3DPointArr[1] := xl;
|
|
a3DPointArr[2] := xh1;
|
|
a3DPointArr[3] := xh;
|
|
|
|
if CheckAdjoiningWallSide(xl1, xl) then
|
|
xSide := T3DSide.Create(ftNetPath, fwtInner, aWallSideType, self)
|
|
else
|
|
xSide := T3DSide.Create(ftNetPath, fwtOuter, aWallSideType, self);
|
|
xSide.CollectWallSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
xl1 := xl;
|
|
xh1 := xh;
|
|
end;
|
|
a3DPointArr[0] := xl1;
|
|
a3DPointArr[1] := l2;
|
|
a3DPointArr[2] := xh1;
|
|
a3DPointArr[3] := h2;
|
|
|
|
if CheckAdjoiningWallSide(xl1, l2) then
|
|
xSide := T3DSide.Create(ftNetPath, fwtInner, aWallSideType, self)
|
|
else
|
|
xSide := T3DSide.Create(ftNetPath, fwtOuter, aWallSideType, self);
|
|
xSide.CollectWallSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWall.CollectWallWithAdjoining', E.Message);
|
|
end;
|
|
end;
|
|
|
|
|
|
constructor T3DWall.Create(aFaces: TList; aNetPath: TNetPath; aParent: T3DRoom);
|
|
begin
|
|
try
|
|
inherited Create;
|
|
FClassName := 'T3DWall';
|
|
FPlanObject := aNetPath;
|
|
if aNetPath <> nil then
|
|
begin
|
|
FIsArc := FPlanObject.isArc;
|
|
FSCSCompon := GetArchObjByCADObj(aNetPath);
|
|
FSCSComponID := FSCSCompon.ID;
|
|
FName := FSCSCompon.Name + ' ' + FSCSCompon.NameMark;
|
|
end;
|
|
FWallElements := TList.Create;
|
|
FSides := TList.Create;
|
|
FParent := aParent;
|
|
if aFaces <> nil then
|
|
ParseWall(aFaces);
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWall.Create', E.Message);
|
|
end;
|
|
end;
|
|
|
|
function T3DWall.GetAdjoiningWalls: TList;
|
|
var
|
|
i, j: integer;
|
|
CAD: TF_CAD;
|
|
CADWalls: TList;
|
|
WallConture: TDoublePointArr;
|
|
Wall: TNetPath;
|
|
NetPathConture, NetInnerConture, NetOuterConture: TDoublePointArr;
|
|
rad1, rad2: Double;
|
|
begin
|
|
try
|
|
Result := TList.Create;
|
|
WallConture := FPlanObject.GetConturePolygon;
|
|
NetInnerConture := FPlanObject.Net.GetRoomInnerConture;
|
|
NetOuterConture := FPlanObject.Net.GetRoomOuterConture;
|
|
|
|
CAD := TF_CAD(TPowerCad(FPlanObject.Net.Owner).Owner);
|
|
CADWalls := GetAllOtherNetWallsFromCAD(CAD, FPlanObject.Net);
|
|
|
|
if CADWalls.Count > 0 then
|
|
begin
|
|
// çàäàåì êîíòóð ñòåíû
|
|
SetLength(NetPathConture, 4);
|
|
NetPathConture[0] := FPlanObject.l1;
|
|
NetPathConture[1] := FPlanObject.l2;
|
|
NetPathConture[2] := FPlanObject.r2;
|
|
NetPathConture[3] := FPlanObject.r1;
|
|
rad1 := GetRadOfLine(FPlanObject.p1^, FPlanObject.p2^);
|
|
// Ïåðåáèðàåì âñå ñòåíû è ñìîòðèì ïîïàäàþò ëè îíè â äàííóþ ñòåíó ïî êîîðäèíàòàì
|
|
for i := 0 to CADWalls.Count - 1 do
|
|
begin
|
|
Wall := TNetPath(CADWalls[i]);
|
|
rad2 := GetRadOfLine(Wall.p1^, Wall.p2^);
|
|
|
|
if (PtInPolygon(NetInnerConture, Wall.p1^) and AnglesCMP(rad1, rad2) and PointDistCMP(Wall.p1^, FPlanObject)) or
|
|
(PtInPolygon(NetOuterConture, Wall.p1^) and AnglesCMP(rad1, rad2) and PointDistCMP(Wall.p1^, FPlanObject))then
|
|
Result.Add(Wall.p1);
|
|
if (PtInPolygon(NetInnerConture, Wall.p2^) and AnglesCMP(rad1, rad2) and PointDistCMP(Wall.p2^, FPlanObject)) or
|
|
(PtInPolygon(NetOuterConture, Wall.p2^) and AnglesCMP(rad1, rad2) and PointDistCMP(Wall.p2^, FPlanObject)) then
|
|
Result.Add(Wall.p2);
|
|
end;
|
|
end;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWall.GetAdjoiningWalls', E.Message);
|
|
end;
|
|
end;
|
|
|
|
function GetArcWallPointsAll(aPoints: T3DPointArray; FPlanObject: TNetPath; isWall: boolean = False): T3DPointArray;
|
|
var
|
|
Fpoints: T2DPointArray;
|
|
Radius: Double;
|
|
a1,a2: Double;
|
|
Cnt: Integer;
|
|
i, idx: Integer;
|
|
p1, p2: TDoublePoint;
|
|
FPointsInOrder: Boolean; // Íîâûå òî÷êè äîáàâëÿòü â ïîðÿäêå êîòîðîì ïðèøëè, èëè îáðàòíîì
|
|
OldDxfMode: Boolean;
|
|
|
|
procedure AddPointToArray(APoint: TDoublePoint; var AArray: T3DPointArray);
|
|
begin
|
|
SetLength(AArray, Length(AArray)+1);
|
|
AArray[Length(AArray)-1] := APoint;
|
|
end;
|
|
|
|
begin
|
|
try
|
|
SetLength(Result, 0);
|
|
// 1-st ARC
|
|
p1 := aPoints[0];
|
|
p2 := aPoints[1];
|
|
Radius := GetLineLenght(p1, FPlanObject.ArcCenter);
|
|
a1 := GetRadOfLine(FPlanObject.ArcCenter, p1);
|
|
a2 := GetRadOfLine(FPlanObject.ArcCenter, p2);
|
|
if Not FPlanObject.Inverted then
|
|
ExchangeDouble(a1, a2);
|
|
OldDxfMode := DxfMode; // ïîâûøàåì òî÷íîñòü - êîëè÷åñòâî òî÷åê äëÿ äóãè
|
|
DxfMode := True;
|
|
try
|
|
BezierArcPoints(FPoints, FPlanObject.ArcCenter.x, FPlanObject.ArcCenter.y, Radius, a1, a2);
|
|
finally
|
|
DxfMode := OldDxfMode;
|
|
end;
|
|
Cnt := Length(FPoints);
|
|
|
|
AddPointToArray(p1, Result);
|
|
if Cnt > 2 then
|
|
begin
|
|
FPointsInOrder := EQDP(p1, DoublePoint(FPoints[0].x, FPoints[0].y));
|
|
for i := 1 to cnt - 2 do
|
|
begin
|
|
if FPointsInOrder then
|
|
idx := i
|
|
else
|
|
idx := cnt - i - 1;
|
|
if (i mod 10) = 0 then
|
|
AddPointToArray(DoublePoint(FPoints[idx].x, FPoints[idx].y, p1.z), Result);
|
|
end;
|
|
end;
|
|
AddPointToArray(p2, Result);
|
|
|
|
if length(aPoints) > 3 then
|
|
begin
|
|
// 2-nd ARC
|
|
p1 := aPoints[2];
|
|
p2 := aPoints[3];
|
|
Radius := GetLineLenght(p1, FPlanObject.ArcCenter);
|
|
a1 := GetRadOfLine(FPlanObject.ArcCenter, p1);
|
|
a2 := GetRadOfLine(FPlanObject.ArcCenter, p2);
|
|
if Not FPlanObject.Inverted then
|
|
ExchangeDouble(a1, a2);
|
|
OldDxfMode := DxfMode; // ïîâûøàåì òî÷íîñòü - êîëè÷åñòâî òî÷åê äëÿ äóãè
|
|
DxfMode := True;
|
|
try
|
|
BezierArcPoints(FPoints, FPlanObject.ArcCenter.x, FPlanObject.ArcCenter.y, Radius, a1, a2);
|
|
finally
|
|
DxfMode := OldDxfMode;
|
|
end;
|
|
Cnt := Length(FPoints);
|
|
|
|
if isWall then
|
|
begin
|
|
AddPointToArray(p1, Result);
|
|
if Cnt > 2 then
|
|
begin
|
|
FPointsInOrder := EQDP(p1, DoublePoint(FPoints[0].x, FPoints[0].y));
|
|
for i := 1 to cnt - 2 do
|
|
begin
|
|
if FPointsInOrder then
|
|
idx := i
|
|
else
|
|
idx := cnt - i - 1;
|
|
if (i mod 10) = 0 then
|
|
AddPointToArray(DoublePoint(FPoints[idx].x, FPoints[idx].y, p2.z), Result);
|
|
end;
|
|
end;
|
|
AddPointToArray(p2, Result);
|
|
end
|
|
else
|
|
begin
|
|
AddPointToArray(p2, Result);
|
|
if Cnt > 2 then
|
|
begin
|
|
FPointsInOrder := EQDP(p2, DoublePoint(FPoints[0].x, FPoints[0].y));
|
|
for i := 1 to cnt - 2 do
|
|
begin
|
|
if FPointsInOrder then
|
|
idx := i
|
|
else
|
|
idx := cnt - i - 1;
|
|
if (i mod 10) = 0 then
|
|
AddPointToArray(DoublePoint(FPoints[idx].x, FPoints[idx].y, p2.z), Result);
|
|
end;
|
|
end;
|
|
AddPointToArray(p1, Result);
|
|
end;
|
|
end;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWall.GetArcWallPoints', E.Message);
|
|
end;
|
|
end;
|
|
|
|
|
|
function T3DWall.GetArcWallPoints(aPoints: T3DPointArray; isWall: boolean = False): T3DPointArray;
|
|
begin
|
|
result := GetArcWallPointsAll(aPoints, FPlanObject, isWall);
|
|
end;
|
|
|
|
function T3DWall.GetFullDoors: TList;
|
|
var
|
|
i, j: integer;
|
|
CAD: TF_CAD;
|
|
CADWallChilds: TList;
|
|
WallChild: TNetDoor;
|
|
WallConture: TDoublePointArr;
|
|
xl1, xr1, da1, da2, db1, db2: TDoublePoint;
|
|
xlen, ylen, len1, len2: double;
|
|
Inserted: Boolean;
|
|
begin
|
|
try
|
|
Result := TList.Create;
|
|
for i := 0 to FPlanObject.Doors.Count - 1 do
|
|
Result.Add(FPlanObject.Doors[i]);
|
|
|
|
// èñêàòü ñî ñìåæíûõ ñòåí îáùèå îáüåêòû
|
|
CAD := TF_CAD(TPowerCad(FPlanObject.Net.Owner).Owner);
|
|
CADWallChilds := GetAllWallChildsFromCAD(CAD, []);
|
|
|
|
if CADWallChilds.Count > 0 then
|
|
begin
|
|
FPlanObject.DefineDoorsOwner;
|
|
WallConture := FPlanObject.GetConturePolygon;
|
|
// Ïåðåáèðàåì âñå îáúåêòû è ñìîòðèì ïîïàäàþò ëè îíè â ñòåíó ïî êîîðäèíàòàì
|
|
for i := 0 to CADWallChilds.Count - 1 do
|
|
begin
|
|
WallChild := TNetDoor(CADWallChilds[i]);
|
|
if WallChild.FPath <> FPlanObject then
|
|
begin
|
|
if IsPtInPolygon(WallChild.p1, WallConture) and IsPtInPolygon(WallChild.p2, WallConture) then
|
|
begin
|
|
len1 := GetLineLenght(FPlanObject.l1, WallChild.a1);
|
|
len2 := GetLineLenght(FPlanObject.l1, WallChild.a2);
|
|
ylen := Min(len1, len2);
|
|
Inserted := False;
|
|
for j := 0 to Result.Count - 1 do
|
|
begin
|
|
len1 := GetLineLenght(FPlanObject.l1, TNetDoor(Result[j]).a1);
|
|
len2 := GetLineLenght(FPlanObject.l1, TNetDoor(Result[j]).a2);
|
|
xlen := Min(len1, len2);
|
|
if ylen < xlen then
|
|
begin
|
|
Result.Insert(j, WallChild);
|
|
Inserted := True;
|
|
break;
|
|
end;
|
|
end;
|
|
if not Inserted then
|
|
Result.Add(WallChild);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWall.GetFullDoors', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DWall.ParseWall(aFaces: TList);
|
|
var
|
|
aDoor, PrevDoor: TNetDoor;
|
|
i, j, k: integer;
|
|
WallComponID: Integer;
|
|
l1, l2, r1, r2: TDoublePoint;
|
|
DoorSCSCompon, PrevDoorSCSCompon, BalconDoor, BalconWnd, InnerSlope, OuterSlope: TSCSComponent;
|
|
wall_h1, wall_h2, door_h1, door_h2, wnd_h1, wnd_h2, w, door_w, wnd_w, corner_side1, corner_side2: double;
|
|
Points, Points1, Points2: T3DPointArray;
|
|
xl1, xr1, da1, da2, db1, db2: TDoublePoint;
|
|
ba1, ba2, ba3, bb1, bb2, bb3: TDoublePoint;
|
|
ca1, ca2, cb1, cb2: TDoublePoint;
|
|
AllDoors, AdjoiningList, WallSides: TList;
|
|
len1, len2: double;
|
|
hor_a1, hor_a2, hor_b1, hor_b2, ver_a, ver_b, depth_a, depth_b: double;
|
|
WallType: TFaceWallType;
|
|
WallViewType: TWallViewType;
|
|
xWallElement, xPrevWallElement: T3DWallElement;
|
|
xSlope: T3DSlope;
|
|
xSide: T3DSide;
|
|
Corners: TSCSComponents;
|
|
|
|
begin
|
|
try
|
|
WallComponID := FSCSComponID;
|
|
wall_h1 := FSCSCompon.GetPropertyValueAsFloat(pnCoordZ) * FScaleDelta;
|
|
wall_h2 := wall_h1 + FSCSCompon.GetPropertyValueAsFloat(pnHeight) * FScaleDelta;
|
|
|
|
// MARK
|
|
Corners := GetArchCornersForWall(FSCSCompon);
|
|
corner_side1 := Corners[0].GetPropertyValueAsFloat(pnHeight) * FScaleDelta;
|
|
if corner_side1 = 0 then
|
|
corner_side1 := wall_h2;
|
|
corner_side2 := Corners[1].GetPropertyValueAsFloat(pnHeight) * FScaleDelta;
|
|
if corner_side2 = 0 then
|
|
corner_side2 := wall_h2;
|
|
//
|
|
|
|
SetLength(Points, 8);
|
|
WallSides := nil;
|
|
// âñå äâåðè ñ ó÷åòîì ñìåæíûõ
|
|
AllDoors := GetFullDoors;
|
|
// åñòü ëè ñìåæíûå ñòåíû ñ ýòîé
|
|
// åñëè 3Ä ïî îòäåëüíîé êîìíàòå òî èñêàòü íåò ñìûñëà
|
|
if FSingleRoom then
|
|
AdjoiningList := TList.Create
|
|
else
|
|
AdjoiningList := GetAdjoiningWalls;
|
|
// åñëè âíóòðè åñòü äâåðè, îêíà ... (àëãîðèòì ïîñòðîåíèÿ ¹1)
|
|
if AllDoors.Count > 0 then
|
|
begin
|
|
xl1 := FPlanObject.l1;
|
|
xr1 := FPlanObject.r1;
|
|
PrevDoor := nil;
|
|
PrevDoorSCSCompon := nil;
|
|
xPrevWallElement := nil;
|
|
|
|
for j := 0 to AllDoors.Count - 1 do
|
|
begin
|
|
aDoor := TNetDoor(AllDoors[j]);
|
|
xWallElement := T3DWallElement.Create(aFaces, aDoor, aDoor.DoorObjType, Self);
|
|
FWallElements.Add(xWallElement);
|
|
DoorSCSCompon := GetArchObjByCADObj(aDoor);
|
|
// îïðåäåëèòü ÷àñòü ñòåíû, îò íà÷àëà äî ñëåä. îáüåêòà
|
|
len1 := GetLineLenght(xl1, aDoor.a1);
|
|
len2 := GetLineLenght(xl1, aDoor.a2);
|
|
if len1 < len2 then
|
|
begin
|
|
da1 := aDoor.a1;
|
|
da2 := aDoor.a2;
|
|
db1 := aDoor.b1;
|
|
db2 := aDoor.b2;
|
|
end
|
|
else
|
|
begin
|
|
da1 := aDoor.b2;
|
|
da2 := aDoor.b1;
|
|
db1 := aDoor.a2;
|
|
db2 := aDoor.a1;
|
|
end;
|
|
ca1 := aDoor.ca1;
|
|
ca2 := aDoor.ca2;
|
|
cb1 := aDoor.cb1;
|
|
cb2 := aDoor.cb2;
|
|
|
|
// ñêîððåêòèðîâàòü òî÷êè ñòåíû ñ ó÷åòîì îòêîñîâ
|
|
hor_a1 := 0;
|
|
hor_b1 := 0;
|
|
hor_a2 := 0;
|
|
hor_b2 := 0;
|
|
|
|
WallViewType := [];
|
|
if PrevDoor <> nil then
|
|
begin
|
|
WallType := GetWallTypeByDoorType(PrevDoor);
|
|
if WallType in [fwtDoorSlope, fwtWindowSlope, fwtBalconSlope] then
|
|
WallViewType := WallViewType + [wvtNoLeftSide];
|
|
end;
|
|
WallType := GetWallTypeByDoorType(aDoor);
|
|
if WallType in [fwtDoorSlope, fwtWindowSlope, fwtBalconSlope] then
|
|
begin
|
|
WallViewType := WallViewType + [wvtNoRightSide];
|
|
InnerSlope := GetChildComponByIsLine(DoorSCSCompon, ctArhInnerSlope); // Âíóòðåííèé îòêîñ
|
|
// Îêíî
|
|
if WallType = fwtWindowSlope then
|
|
begin
|
|
OuterSlope := GetChildComponByIsLine(DoorSCSCompon, ctArhOuterSlope); // Âíåøíèé îòêîñ
|
|
// åñòü îêíî è íå ñìåæíàÿ ñòåíà, òî áðàòü âíåøíèå îòêîñû
|
|
if (AdjoiningList.Count = 0) and (OuterSlope <> nil) then
|
|
begin
|
|
hor_a1 := (OuterSlope.GetPropertyValueAsFloat(pnWidth) - DoorSCSCompon.GetPropertyValueAsFloat(pnWidth)) * FScaleDelta / 2;
|
|
hor_a2 := hor_a1;
|
|
ver_a := (OuterSlope.GetPropertyValueAsFloat(pnHeight) - DoorSCSCompon.GetPropertyValueAsFloat(pnHeight)) * FScaleDelta;
|
|
depth_a := OuterSlope.GetPropertyValueAsFloat(pnDepth) * FScaleDelta;
|
|
end
|
|
else
|
|
begin
|
|
ver_a := 0;
|
|
depth_a := 0;
|
|
end;
|
|
if InnerSlope <> nil then
|
|
begin
|
|
hor_b1 := (InnerSlope.GetPropertyValueAsFloat(pnWidth) - DoorSCSCompon.GetPropertyValueAsFloat(pnWidth)) * FScaleDelta / 2;
|
|
hor_b2 := hor_b1;
|
|
ver_b := (InnerSlope.GetPropertyValueAsFloat(pnHeight) - DoorSCSCompon.GetPropertyValueAsFloat(pnHeight)) * FScaleDelta;
|
|
depth_b := InnerSlope.GetPropertyValueAsFloat(pnDepth) * FScaleDelta;
|
|
end
|
|
else
|
|
begin
|
|
ver_b := 0;
|
|
depth_b := 0;
|
|
end;
|
|
end
|
|
else
|
|
// Äâåðü
|
|
if WallType = fwtDoorSlope then
|
|
begin
|
|
if InnerSlope <> nil then
|
|
begin
|
|
hor_a1 := (InnerSlope.GetPropertyValueAsFloat(pnWidth) - DoorSCSCompon.GetPropertyValueAsFloat(pnWidth)) * FScaleDelta / 2;
|
|
hor_a2 := hor_a1;
|
|
hor_b1 := hor_a1;
|
|
hor_b2 := hor_a1;
|
|
ver_a := (InnerSlope.GetPropertyValueAsFloat(pnHeight) - DoorSCSCompon.GetPropertyValueAsFloat(pnHeight)) * FScaleDelta;
|
|
ver_b := ver_a;
|
|
depth_a := InnerSlope.GetPropertyValueAsFloat(pnDepth) * FScaleDelta;
|
|
depth_b := InnerSlope.GetPropertyValueAsFloat(pnDepth) * FScaleDelta;
|
|
end
|
|
else
|
|
begin
|
|
ver_a := 0;
|
|
ver_b := 0;
|
|
depth_a := 0;
|
|
depth_b := 0;
|
|
end;
|
|
end
|
|
else
|
|
// Áàëêîí
|
|
if WallType = fwtBalconSlope then
|
|
begin
|
|
if InnerSlope <> nil then
|
|
begin
|
|
BalconDoor := GetChildComponByIsLine(DoorSCSCompon, ctArhDoor); // Äâåðü áàëêîíà
|
|
hor_a1 := (InnerSlope.GetPropertyValueAsFloat(pnWidth) - DoorSCSCompon.GetPropertyValueAsFloat(pnWidth)) * FScaleDelta / 2;
|
|
hor_a2 := hor_a1;
|
|
hor_b1 := hor_a1;
|
|
hor_b2 := hor_a1;
|
|
ver_a := (InnerSlope.GetPropertyValueAsFloat(pnHeight) - BalconDoor.GetPropertyValueAsFloat(pnHeight)) * FScaleDelta;
|
|
ver_b := ver_a;
|
|
depth_a := InnerSlope.GetPropertyValueAsFloat(pnDepth) * FScaleDelta;
|
|
depth_b := InnerSlope.GetPropertyValueAsFloat(pnDepth) * FScaleDelta;
|
|
end
|
|
else
|
|
begin
|
|
ver_a := 0;
|
|
ver_b := 0;
|
|
depth_a := 0;
|
|
depth_b := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
GetWallPointsWithSlope(da1, da2, db1, db2, hor_a1, hor_a2, hor_b1, hor_b2);
|
|
GetDoorPointsWithSlope(ca1, da1, depth_a);
|
|
GetDoorPointsWithSlope(ca2, da2, depth_a);
|
|
GetDoorPointsWithSlope(cb1, db1, depth_b);
|
|
GetDoorPointsWithSlope(cb2, db2, depth_b);
|
|
|
|
Points[0] := xl1;
|
|
Points[0].z := wall_h1;
|
|
Points[1] := da1;
|
|
Points[1].z := wall_h1;
|
|
Points[2] := xr1;
|
|
Points[2].z := wall_h1;
|
|
Points[3] := db1;
|
|
Points[3].z := wall_h1;
|
|
|
|
{
|
|
Points[4] := xl1;
|
|
Points[4].z := wall_h2;
|
|
Points[5] := da1;
|
|
Points[5].z := wall_h2;
|
|
Points[6] := xr1;
|
|
Points[6].z := wall_h2;
|
|
Points[7] := db1;
|
|
Points[7].z := wall_h2;
|
|
}
|
|
|
|
|
|
// MARK
|
|
|
|
// ïåðâûé áëîê - âçÿòü âûñîòó ñ ìîäïîèíòà
|
|
if j = 0 then
|
|
begin
|
|
Points[4] := xl1;
|
|
Points[4].z := corner_side1;
|
|
Points[5] := da1;
|
|
Points[5].z := CalcPointHeight(FPlanObject.l1, FPlanObject.l2, da1, corner_side1, corner_side2);
|
|
Points[6] := xr1;
|
|
Points[6].z := corner_side1;
|
|
Points[7] := db1;
|
|
Points[7].z := CalcPointHeight(FPlanObject.r1, FPlanObject.r2, db1, corner_side1, corner_side2);
|
|
end
|
|
else
|
|
begin
|
|
Points[4] := xl1;
|
|
Points[4].z := CalcPointHeight(FPlanObject.l1, FPlanObject.l2, xl1, corner_side1, corner_side2);
|
|
Points[5] := da1;
|
|
Points[5].z := CalcPointHeight(FPlanObject.l1, FPlanObject.l2, da1, corner_side1, corner_side2);
|
|
Points[6] := xr1;
|
|
Points[6].z := CalcPointHeight(FPlanObject.r1, FPlanObject.r2, xr1, corner_side1, corner_side2);
|
|
Points[7] := db1;
|
|
Points[7].z := CalcPointHeight(FPlanObject.r1, FPlanObject.r2, db1, corner_side1, corner_side2);
|
|
end;
|
|
WallSides := CollectWall(aFaces, Points, AdjoiningList, WallViewType);
|
|
// ïîñòàâèòü òèï ñòåíû ïî ïðåäûäóùåìó îáüåêòó TNetDoor
|
|
if (j > 0) and (PrevDoor <> nil) then
|
|
begin
|
|
WallType := GetWallTypeByDoorType(PrevDoor);
|
|
if WallType in [fwtNiche, fwtArc] then
|
|
SetWallTypeToWallSide(WallSides, wstLeftSide, WallType, xWallElement);
|
|
end;
|
|
// ïîñòàâèòü òèï ñòåíû ïî ñëåäóþùåìó îáüåêòó TNetDoor
|
|
WallType := GetWallTypeByDoorType(aDoor);
|
|
if WallType in [fwtNiche, fwtArc] then
|
|
SetWallTypeToWallSide(WallSides, wstRightSide, WallType, xWallElement);
|
|
|
|
xl1 := da2;
|
|
xr1 := db2;
|
|
|
|
// Îáüåêò - Äâåðü
|
|
if aDoor.DoorObjType = dotDoor then
|
|
begin
|
|
door_h1 := DoorSCSCompon.GetPropertyValueAsFloat(pnCoordZ) * FScaleDelta;
|
|
if door_h1 < FStartDoorObject then
|
|
door_h1 := FStartDoorObject;
|
|
door_h2 := door_h1 + DoorSCSCompon.GetPropertyValueAsFloat(pnHeight) * FScaleDelta;
|
|
w := DoorSCSCompon.GetPropertyValueAsFloat(pnWidth);
|
|
|
|
// ïîñòðîèòü äâåðü
|
|
Points[0] := ca1;
|
|
Points[0].z := door_h1;
|
|
Points[1] := ca2;
|
|
Points[1].z := door_h1;
|
|
Points[2] := cb1;
|
|
Points[2].z := door_h1;
|
|
Points[3] := cb2;
|
|
Points[3].z := door_h1;
|
|
Points[4] := ca1;
|
|
Points[4].z := door_h2;
|
|
Points[5] := ca2;
|
|
Points[5].z := door_h2;
|
|
Points[6] := cb1;
|
|
Points[6].z := door_h2;
|
|
Points[7] := cb2;
|
|
Points[7].z := door_h2;
|
|
xWallElement.CollectDoor(aFaces, Points);
|
|
|
|
// ïîñòðîèòü áëîê ñòåíû ñíèçó
|
|
Points[0] := da1;
|
|
Points[0].z := wall_h1;
|
|
Points[1] := da2;
|
|
Points[1].z := wall_h1;
|
|
Points[2] := db1;
|
|
Points[2].z := wall_h1;
|
|
Points[3] := db2;
|
|
Points[3].z := wall_h1;
|
|
Points[4] := da1;
|
|
Points[4].z := door_h1 - FDoorObjectDelta;
|
|
Points[5] := da2;
|
|
Points[5].z := door_h1 - FDoorObjectDelta;
|
|
Points[6] := db1;
|
|
Points[6].z := door_h1 - FDoorObjectDelta;
|
|
Points[7] := db2;
|
|
Points[7].z := door_h1 - FDoorObjectDelta;
|
|
WallSides := CollectWall(aFaces, Points, AdjoiningList, []);
|
|
SetWallTypeToWallSide(WallSides, wstUpper, fwtDoorSlope, xWallElement);
|
|
|
|
// ïîñòðîèòü áëîê ñòåíû ñâåðõó
|
|
Points[0] := da1;
|
|
Points[0].z := door_h2 + ver_a;
|
|
Points[1] := da2;
|
|
Points[1].z := door_h2 + ver_a;
|
|
Points[2] := db1;
|
|
Points[2].z := door_h2 + ver_b;
|
|
Points[3] := db2;
|
|
Points[3].z := door_h2 + ver_b;
|
|
Points[4] := da1;
|
|
|
|
{
|
|
Points[4].z := wall_h2;
|
|
Points[5] := da2;
|
|
Points[5].z := wall_h2;
|
|
Points[6] := db1;
|
|
Points[6].z := wall_h2;
|
|
Points[7] := db2;
|
|
Points[7].z := wall_h2;
|
|
}
|
|
|
|
// MARK
|
|
Points[4].z := CalcPointHeight(FPlanObject.l1, FPlanObject.l2, da1, corner_side1, corner_side2);
|
|
Points[5] := da2;
|
|
Points[5].z := CalcPointHeight(FPlanObject.l1, FPlanObject.l2, da2, corner_side1, corner_side2);
|
|
Points[6] := db1;
|
|
Points[6].z := CalcPointHeight(FPlanObject.r1, FPlanObject.r2, db1, corner_side1, corner_side2);
|
|
Points[7] := db2;
|
|
Points[7].z := CalcPointHeight(FPlanObject.r1, FPlanObject.r2, db2, corner_side1, corner_side2);
|
|
WallSides := CollectWall(aFaces, Points, AdjoiningList, [wvtNoUnder]);
|
|
|
|
// ïîñòðîèòü îòêîñû äëÿ äâåðè
|
|
if InnerSlope <> nil then
|
|
begin
|
|
xSlope := T3DSlope.Create(aFaces, aDoor, xWallElement);
|
|
xSlope.FSCSCompon := GetChildComponByIsLine(xWallElement.FSCSCompon, ctArhInnerSlope);
|
|
xSlope.FSCSComponID := xSlope.FSCSCompon.ID;
|
|
xSlope.FName := xSlope.FSCSCompon.Name;
|
|
xWallElement.FSlopes.Add(xSlope);
|
|
// âíåøíèå
|
|
Points[0] := da1;
|
|
Points[0].z := door_h1;
|
|
Points[1] := da1;
|
|
Points[1].z := door_h2 + ver_a;
|
|
Points[2] := ca1;
|
|
Points[2].z := door_h1;
|
|
Points[3] := ca1;
|
|
Points[3].z := door_h2;
|
|
xSide := T3DSide.Create(ftNetPath, fwtDoorSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
Points[0] := da2;
|
|
Points[0].z := door_h1;
|
|
Points[1] := da2;
|
|
Points[1].z := door_h2 + ver_a;
|
|
Points[2] := ca2;
|
|
Points[2].z := door_h1;
|
|
Points[3] := ca2;
|
|
Points[3].z := door_h2;
|
|
xSide := T3DSide.Create(ftNetPath, fwtDoorSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
Points[0] := ca1;
|
|
Points[0].z := door_h2;
|
|
Points[1] := ca2;
|
|
Points[1].z := door_h2;
|
|
Points[2] := da1;
|
|
Points[2].z := door_h2 + ver_a;
|
|
Points[3] := da2;
|
|
Points[3].z := door_h2 + ver_a;
|
|
xSide := T3DSide.Create(ftNetPath, fwtDoorSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
end;
|
|
|
|
if OuterSlope <> nil then
|
|
begin
|
|
// âíóòðåííèå
|
|
Points[0] := db1;
|
|
Points[0].z := door_h1;
|
|
Points[1] := db1;
|
|
Points[1].z := door_h2 + ver_b;
|
|
Points[2] := cb1;
|
|
Points[2].z := door_h1;
|
|
Points[3] := cb1;
|
|
Points[3].z := door_h2;
|
|
xSide := T3DSide.Create(ftNetPath, fwtDoorSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
Points[0] := db2;
|
|
Points[0].z := door_h1;
|
|
Points[1] := db2;
|
|
Points[1].z := door_h2 + ver_b;
|
|
Points[2] := cb2;
|
|
Points[2].z := door_h1;
|
|
Points[3] := cb2;
|
|
Points[3].z := door_h2;
|
|
xSide := T3DSide.Create(ftNetPath, fwtDoorSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
Points[0] := cb1;
|
|
Points[0].z := door_h2;
|
|
Points[1] := cb2;
|
|
Points[1].z := door_h2;
|
|
Points[2] := db1;
|
|
Points[2].z := door_h2 + ver_b;
|
|
Points[3] := db2;
|
|
Points[3].z := door_h2 + ver_b;
|
|
xSide := T3DSide.Create(ftNetPath, fwtDoorSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
end;
|
|
end;
|
|
|
|
// Îáüåêò - Îêíî
|
|
if aDoor.DoorObjType = dotWindow then
|
|
begin
|
|
door_h1 := DoorSCSCompon.GetPropertyValueAsFloat(pnCoordZ) * FScaleDelta;
|
|
if door_h1 < FStartDoorObject then
|
|
door_h1 := FStartDoorObject;
|
|
door_h2 := door_h1 + DoorSCSCompon.GetPropertyValueAsFloat(pnHeight) * FScaleDelta;
|
|
w := DoorSCSCompon.GetPropertyValueAsFloat(pnWidth);
|
|
|
|
// ïîñòðîèòü îêíî
|
|
Points[0] := ca1;
|
|
Points[0].z := door_h1;
|
|
Points[1] := ca2;
|
|
Points[1].z := door_h1;
|
|
Points[2] := cb1;
|
|
Points[2].z := door_h1;
|
|
Points[3] := cb2;
|
|
Points[3].z := door_h1;
|
|
Points[4] := ca1;
|
|
Points[4].z := door_h2;
|
|
Points[5] := ca2;
|
|
Points[5].z := door_h2;
|
|
Points[6] := cb1;
|
|
Points[6].z := door_h2;
|
|
Points[7] := cb2;
|
|
Points[7].z := door_h2;
|
|
xWallElement.CollectWindow(aFaces, Points);
|
|
|
|
// ïîñòðîèòü áëîê ñòåíû ñíèçó
|
|
Points[0] := da1;
|
|
Points[0].z := wall_h1;
|
|
Points[1] := da2;
|
|
Points[1].z := wall_h1;
|
|
Points[2] := db1;
|
|
Points[2].z := wall_h1;
|
|
Points[3] := db2;
|
|
Points[3].z := wall_h1;
|
|
Points[4] := da1;
|
|
Points[4].z := door_h1 - FDoorObjectDelta;
|
|
Points[5] := da2;
|
|
Points[5].z := door_h1 - FDoorObjectDelta;
|
|
Points[6] := db1;
|
|
Points[6].z := door_h1 - FDoorObjectDelta;
|
|
Points[7] := db2;
|
|
Points[7].z := door_h1 - FDoorObjectDelta;
|
|
WallSides := CollectWall(aFaces, Points, AdjoiningList, []);
|
|
SetWallTypeToWallSide(WallSides, wstUpper, fwtWindowSlope, xWallElement);
|
|
|
|
// ïîñòðîèòü áëîê ñòåíû ñâåðõó
|
|
Points[0] := da1;
|
|
Points[0].z := door_h2 + ver_a;
|
|
Points[1] := da2;
|
|
Points[1].z := door_h2 + ver_a;
|
|
Points[2] := db1;
|
|
Points[2].z := door_h2 + ver_b;
|
|
Points[3] := db2;
|
|
Points[3].z := door_h2 + ver_b;
|
|
Points[4] := da1;
|
|
|
|
{
|
|
Points[4].z := wall_h2;
|
|
Points[5] := da2;
|
|
Points[5].z := wall_h2;
|
|
Points[6] := db1;
|
|
Points[6].z := wall_h2;
|
|
Points[7] := db2;
|
|
Points[7].z := wall_h2;
|
|
}
|
|
|
|
// MARK
|
|
Points[4].z := CalcPointHeight(FPlanObject.l1, FPlanObject.l2, da1, corner_side1, corner_side2);
|
|
Points[5] := da2;
|
|
Points[5].z := CalcPointHeight(FPlanObject.l1, FPlanObject.l2, da2, corner_side1, corner_side2);
|
|
Points[6] := db1;
|
|
Points[6].z := CalcPointHeight(FPlanObject.r1, FPlanObject.r2, db1, corner_side1, corner_side2);
|
|
Points[7] := db2;
|
|
Points[7].z := CalcPointHeight(FPlanObject.r1, FPlanObject.r2, db2, corner_side1, corner_side2);
|
|
WallSides := CollectWall(aFaces, Points, AdjoiningList, [wvtNoUnder]);
|
|
|
|
// ïîñòðîèòü îòêîñû äëÿ îêíà
|
|
// âíóòðåííèå
|
|
|
|
{TODO} // äëÿ âíåøíèõ ñäåëàòü àíàëîãè÷íî è äëÿ âñåõ îñòàëüíûõ îáúåêòîâ!!!
|
|
if InnerSlope <> nil then
|
|
begin
|
|
xSlope := T3DSlope.Create(aFaces, aDoor, xWallElement);
|
|
xSlope.FSCSCompon := GetChildComponByIsLine(xWallElement.FSCSCompon, ctArhInnerSlope);
|
|
xSlope.FSCSComponID := xSlope.FSCSCompon.ID;
|
|
xSlope.FName := xSlope.FSCSCompon.Name;
|
|
xWallElement.FSlopes.Add(xSlope);
|
|
Points[0] := db1;
|
|
Points[0].z := door_h1;
|
|
Points[1] := db1;
|
|
Points[1].z := door_h2 + ver_b;
|
|
Points[2] := cb1;
|
|
Points[2].z := door_h1;
|
|
Points[3] := cb1;
|
|
Points[3].z := door_h2;
|
|
xSide := T3DSide.Create(ftNetPath, fwtWindowSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
Points[0] := db2;
|
|
Points[0].z := door_h1;
|
|
Points[1] := db2;
|
|
Points[1].z := door_h2 + ver_b;
|
|
Points[2] := cb2;
|
|
Points[2].z := door_h1;
|
|
Points[3] := cb2;
|
|
Points[3].z := door_h2;
|
|
xSide := T3DSide.Create(ftNetPath, fwtWindowSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
Points[0] := cb1;
|
|
Points[0].z := door_h2;
|
|
Points[1] := cb2;
|
|
Points[1].z := door_h2;
|
|
Points[2] := db1;
|
|
Points[2].z := door_h2 + ver_b;
|
|
Points[3] := db2;
|
|
Points[3].z := door_h2 + ver_b;
|
|
xSide := T3DSide.Create(ftNetPath, fwtWindowSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
end;
|
|
|
|
// âíåøíèå
|
|
if OuterSlope <> nil then
|
|
begin
|
|
xSlope := T3DSlope.Create(aFaces, aDoor, xWallElement);
|
|
xSlope.FSCSCompon := GetChildComponByIsLine(xWallElement.FSCSCompon, ctArhOuterSlope);
|
|
xSlope.FSCSComponID := xSlope.FSCSCompon.ID;
|
|
xSlope.FName := xSlope.FSCSCompon.Name;
|
|
xWallElement.FSlopes.Add(xSlope);
|
|
// end;
|
|
|
|
Points[0] := da1;
|
|
Points[0].z := door_h1;
|
|
Points[1] := da1;
|
|
Points[1].z := door_h2 + ver_a;
|
|
Points[2] := ca1;
|
|
Points[2].z := door_h1;
|
|
Points[3] := ca1;
|
|
Points[3].z := door_h2;
|
|
xSide := T3DSide.Create(ftNetPath, fwtWindowSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
Points[0] := da2;
|
|
Points[0].z := door_h1;
|
|
Points[1] := da2;
|
|
Points[1].z := door_h2 + ver_a;
|
|
Points[2] := ca2;
|
|
Points[2].z := door_h1;
|
|
Points[3] := ca2;
|
|
Points[3].z := door_h2;
|
|
xSide := T3DSide.Create(ftNetPath, fwtWindowSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
Points[0] := ca1;
|
|
Points[0].z := door_h2;
|
|
Points[1] := ca2;
|
|
Points[1].z := door_h2;
|
|
Points[2] := da1;
|
|
Points[2].z := door_h2 + ver_a;
|
|
Points[3] := da2;
|
|
Points[3].z := door_h2 + ver_a;
|
|
xSide := T3DSide.Create(ftNetPath, fwtWindowSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
end;
|
|
end;
|
|
|
|
// Îáüåêò - Áàëêîí
|
|
if aDoor.DoorObjType = dotBalcony then
|
|
begin
|
|
BalconDoor := GetChildComponByIsLine(DoorSCSCompon, ctArhDoor); // Äâåðü áàëêîíà
|
|
BalconWnd := GetChildComponByIsLine(DoorSCSCompon, ctArhWindow); // Îêíî áàëêîíà
|
|
|
|
door_h1 := BalconDoor.GetPropertyValueAsFloat(pnCoordZ) * FScaleDelta;
|
|
if door_h1 < FStartDoorObject then
|
|
door_h1 := FStartDoorObject;
|
|
door_h2 := door_h1 + BalconDoor.GetPropertyValueAsFloat(pnHeight) * FScaleDelta;
|
|
door_w := BalconDoor.GetPropertyValueAsFloat(pnWidth) * FScaleDelta;
|
|
|
|
wnd_h1 := door_h2 - BalconWnd.GetPropertyValueAsFloat(pnHeight) * FScaleDelta;
|
|
if wnd_h1 < FStartDoorObject then
|
|
wnd_h1 := FStartDoorObject;
|
|
wnd_h2 := door_h2;
|
|
wnd_w := BalconWnd.GetPropertyValueAsFloat(pnWidth) * FScaleDelta;
|
|
|
|
// âû÷èñëèòü òî÷êè äëÿ äâåðè è îêíà
|
|
ba1 := ca1;
|
|
ba3 := ca2;
|
|
bb1 := cb1;
|
|
bb3 := cb2;
|
|
GetParallelPoints(ba1, bb1, ba2, bb2, -door_w);
|
|
|
|
Setlength(Points1, 8);
|
|
Setlength(Points2, 8);
|
|
// äëÿ áàëêîííîé äâåðè
|
|
Points1[0] := ba1;
|
|
Points1[0].z := door_h1;
|
|
Points1[1] := ba2;
|
|
Points1[1].z := door_h1;
|
|
Points1[2] := bb1;
|
|
Points1[2].z := door_h1;
|
|
Points1[3] := bb2;
|
|
Points1[3].z := door_h1;
|
|
Points1[4] := ba1;
|
|
Points1[4].z := door_h2;
|
|
Points1[5] := ba2;
|
|
Points1[5].z := door_h2;
|
|
Points1[6] := bb1;
|
|
Points1[6].z := door_h2;
|
|
Points1[7] := bb2;
|
|
Points1[7].z := door_h2;
|
|
// äëÿ áàëêîííîãî îêíà
|
|
Points2[0] := ba2;
|
|
Points2[0].z := wnd_h1;
|
|
Points2[1] := ba3;
|
|
Points2[1].z := wnd_h1;
|
|
Points2[2] := bb2;
|
|
Points2[2].z := wnd_h1;
|
|
Points2[3] := bb3;
|
|
Points2[3].z := wnd_h1;
|
|
Points2[4] := ba2;
|
|
Points2[4].z := wnd_h2;
|
|
Points2[5] := ba3;
|
|
Points2[5].z := wnd_h2;
|
|
Points2[6] := bb2;
|
|
Points2[6].z := wnd_h2;
|
|
Points2[7] := bb3;
|
|
Points2[7].z := wnd_h2;
|
|
xWallElement.CollectBalcon(aFaces, Points1, Points2);
|
|
|
|
// ïîñòðîèòü áëîê ñòåíû ñíèçó
|
|
Points[0] := da1;
|
|
Points[0].z := wall_h1;
|
|
Points[1] := da2;
|
|
Points[1].z := wall_h1;
|
|
Points[2] := db1;
|
|
Points[2].z := wall_h1;
|
|
Points[3] := db2;
|
|
Points[3].z := wall_h1;
|
|
Points[4] := da1;
|
|
Points[4].z := door_h1 - FDoorObjectDelta;
|
|
Points[5] := da2;
|
|
Points[5].z := door_h1 - FDoorObjectDelta;
|
|
Points[6] := db1;
|
|
Points[6].z := door_h1 - FDoorObjectDelta;
|
|
Points[7] := db2;
|
|
Points[7].z := door_h1 - FDoorObjectDelta;
|
|
WallSides := CollectWall(aFaces, Points, AdjoiningList, []);
|
|
SetWallTypeToWallSide(WallSides, wstUpper, fwtBalconSlope, xWallElement);
|
|
|
|
// ïîñòðîèòü áëîê ñòåíû ñâåðõó
|
|
Points[0] := da1;
|
|
Points[0].z := door_h2 + ver_a;
|
|
Points[1] := da2;
|
|
Points[1].z := door_h2 + ver_a;
|
|
Points[2] := db1;
|
|
Points[2].z := door_h2 + ver_b;
|
|
Points[3] := db2;
|
|
Points[3].z := door_h2 + ver_b;
|
|
Points[4] := da1;
|
|
|
|
{
|
|
Points[4].z := wall_h2;
|
|
Points[5] := da2;
|
|
Points[5].z := wall_h2;
|
|
Points[6] := db1;
|
|
Points[6].z := wall_h2;
|
|
Points[7] := db2;
|
|
Points[7].z := wall_h2;
|
|
}
|
|
|
|
// MARK
|
|
Points[4].z := CalcPointHeight(FPlanObject.l1, FPlanObject.l2, da1, corner_side1, corner_side2);
|
|
Points[5] := da2;
|
|
Points[5].z := CalcPointHeight(FPlanObject.l1, FPlanObject.l2, da2, corner_side1, corner_side2);
|
|
Points[6] := db1;
|
|
Points[6].z := CalcPointHeight(FPlanObject.r1, FPlanObject.r2, db1, corner_side1, corner_side2);
|
|
Points[7] := db2;
|
|
Points[7].z := CalcPointHeight(FPlanObject.r1, FPlanObject.r2, db2, corner_side1, corner_side2);
|
|
WallSides := CollectWall(aFaces, Points, AdjoiningList, [wvtNoUnder]);
|
|
|
|
// äîñòðîèòü áëîê ñòåíû â ïðîåì
|
|
ba1 := da1;
|
|
ba3 := da2;
|
|
bb1 := db1;
|
|
bb3 := db2;
|
|
GetParallelPoints(ba1, bb1, ba2, bb2, -door_w);
|
|
|
|
Points[0] := ba2;
|
|
Points[0].z := door_h1;
|
|
Points[1] := ba3;
|
|
Points[1].z := door_h1;
|
|
Points[2] := bb2;
|
|
Points[2].z := door_h1;
|
|
Points[3] := bb3;
|
|
Points[3].z := door_h1;
|
|
Points[4] := ba2;
|
|
Points[4].z := wnd_h1 - FDoorObjectDelta;
|
|
Points[5] := ba3;
|
|
Points[5].z := wnd_h1 - FDoorObjectDelta;
|
|
Points[6] := bb2;
|
|
Points[6].z := wnd_h1 - FDoorObjectDelta;
|
|
Points[7] := bb3;
|
|
Points[7].z := wnd_h1 - FDoorObjectDelta;
|
|
WallSides := CollectWall(aFaces, Points, AdjoiningList, []);
|
|
SetWallTypeToWallSide(WallSides, wstUpper, fwtBalconSlope, xWallElement);
|
|
SetWallTypeToWallSide(WallSides, wstLeftSide, fwtBalconSlope, xWallElement);
|
|
|
|
// ïîñòðîèòü îòêîñû äëÿ áàëêîíà
|
|
if InnerSlope <> nil then
|
|
begin
|
|
xSlope := T3DSlope.Create(aFaces, aDoor, xWallElement);
|
|
xSlope.FSCSCompon := GetChildComponByIsLine(xWallElement.FSCSCompon, ctArhInnerSlope);
|
|
xSlope.FSCSComponID := xSlope.FSCSCompon.ID;
|
|
xSlope.FName := xSlope.FSCSCompon.Name;
|
|
xWallElement.FSlopes.Add(xSlope);
|
|
|
|
// âíåøíèå
|
|
Points[0] := da1;
|
|
Points[0].z := door_h1;
|
|
Points[1] := da1;
|
|
Points[1].z := door_h2 + ver_a;
|
|
Points[2] := ca1;
|
|
Points[2].z := door_h1;
|
|
Points[3] := ca1;
|
|
Points[3].z := door_h2;
|
|
xSide := T3DSide.Create(ftNetPath, fwtBalconSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
Points[0] := da2;
|
|
Points[0].z := wnd_h1;
|
|
Points[1] := da2;
|
|
Points[1].z := wnd_h2 + ver_a;
|
|
Points[2] := ca2;
|
|
Points[2].z := wnd_h1;
|
|
Points[3] := ca2;
|
|
Points[3].z := wnd_h2;
|
|
xSide := T3DSide.Create(ftNetPath, fwtBalconSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
Points[0] := ca1;
|
|
Points[0].z := door_h2;
|
|
Points[1] := ca2;
|
|
Points[1].z := door_h2;
|
|
Points[2] := da1;
|
|
Points[2].z := door_h2 + ver_a;
|
|
Points[3] := da2;
|
|
Points[3].z := door_h2 + ver_a;
|
|
xSide := T3DSide.Create(ftNetPath, fwtBalconSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
end;
|
|
// âíóòðåííèå
|
|
if OuterSlope <> nil then
|
|
begin
|
|
Points[0] := db1;
|
|
Points[0].z := door_h1;
|
|
Points[1] := db1;
|
|
Points[1].z := door_h2 + ver_b;
|
|
Points[2] := cb1;
|
|
Points[2].z := door_h1;
|
|
Points[3] := cb1;
|
|
Points[3].z := door_h2;
|
|
xSide := T3DSide.Create(ftNetPath, fwtBalconSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
Points[0] := db2;
|
|
Points[0].z := wnd_h1;
|
|
Points[1] := db2;
|
|
Points[1].z := wnd_h2 + ver_b;
|
|
Points[2] := cb2;
|
|
Points[2].z := wnd_h1;
|
|
Points[3] := cb2;
|
|
Points[3].z := wnd_h2;
|
|
xSide := T3DSide.Create(ftNetPath, fwtBalconSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
Points[0] := cb1;
|
|
Points[0].z := door_h2;
|
|
Points[1] := cb2;
|
|
Points[1].z := door_h2;
|
|
Points[2] := db1;
|
|
Points[2].z := door_h2 + ver_b;
|
|
Points[3] := db2;
|
|
Points[3].z := door_h2 + ver_b;
|
|
xSide := T3DSide.Create(ftNetPath, fwtBalconSlope, wstNone, xSlope);
|
|
xSide.CollectWallSide(aFaces, Points);
|
|
xSlope.FSides.Add(xSide);
|
|
end;
|
|
end;
|
|
|
|
// Îáüåêò - Àðêà
|
|
if aDoor.DoorObjType = dotArc then
|
|
begin
|
|
door_h1 := 0;
|
|
door_h2 := DoorSCSCompon.GetPropertyValueAsFloat(pnHeight) * FScaleDelta;
|
|
w := DoorSCSCompon.GetPropertyValueAsFloat(pnWidth);
|
|
|
|
// ïîñòðîèòü àðêó
|
|
{à ÷òî ñòðîèòü åñëè îíà ïóñòàÿ}
|
|
|
|
// ïîñòðîèòü áëîê ñòåíû ñâåðõó
|
|
Points[0] := aDoor.a1;
|
|
Points[0].z := door_h2;
|
|
Points[1] := aDoor.a2;
|
|
Points[1].z := door_h2;
|
|
Points[2] := aDoor.b1;
|
|
Points[2].z := door_h2;
|
|
Points[3] := aDoor.b2;
|
|
Points[3].z := door_h2;
|
|
Points[4] := aDoor.a1;
|
|
|
|
{
|
|
Points[4].z := wall_h2;
|
|
Points[5] := aDoor.a2;
|
|
Points[5].z := wall_h2;
|
|
Points[6] := aDoor.b1;
|
|
Points[6].z := wall_h2;
|
|
Points[7] := aDoor.b2;
|
|
Points[7].z := wall_h2;
|
|
}
|
|
|
|
// MARK
|
|
Points[4].z := CalcPointHeight(FPlanObject.l1, FPlanObject.l2, aDoor.a1, corner_side1, corner_side2);
|
|
Points[5] := aDoor.a2;
|
|
Points[5].z := CalcPointHeight(FPlanObject.l1, FPlanObject.l2, aDoor.a2, corner_side1, corner_side2);
|
|
Points[6] := aDoor.b1;
|
|
Points[6].z := CalcPointHeight(FPlanObject.r1, FPlanObject.r2, aDoor.b1, corner_side1, corner_side2);
|
|
Points[7] := aDoor.b2;
|
|
Points[7].z := CalcPointHeight(FPlanObject.r1, FPlanObject.r2, aDoor.b2, corner_side1, corner_side2);
|
|
WallSides := CollectWall(aFaces, Points, AdjoiningList, []);
|
|
SetWallTypeToWallSide(WallSides, wstUnder, fwtArc, xWallElement);
|
|
//xWallElement.ReplaceArcSides;
|
|
end;
|
|
|
|
// Îáüåêò - Íèøà
|
|
if aDoor.DoorObjType = dotNiche then
|
|
begin
|
|
door_h1 := DoorSCSCompon.GetPropertyValueAsFloat(pnCoordZ) * FScaleDelta;
|
|
if door_h1 < FStartDoorObject then
|
|
door_h1 := FStartDoorObject;
|
|
door_h2 := door_h1 + DoorSCSCompon.GetPropertyValueAsFloat(pnHeight) * FScaleDelta;
|
|
w := DoorSCSCompon.GetPropertyValueAsFloat(pnWidth);
|
|
|
|
// äîñòðîèòü áëîê ñòåíû îò íèøû
|
|
Points[0] := aDoor.a1;
|
|
Points[0].z := door_h1;
|
|
Points[1] := aDoor.a2;
|
|
Points[1].z := door_h1;
|
|
Points[2] := aDoor.ca1;
|
|
Points[2].z := door_h1;
|
|
Points[3] := aDoor.ca2;
|
|
Points[3].z := door_h1;
|
|
Points[4] := aDoor.a1;
|
|
Points[4].z := door_h2;
|
|
Points[5] := aDoor.a2;
|
|
Points[5].z := door_h2;
|
|
Points[6] := aDoor.ca1;
|
|
Points[6].z := door_h2;
|
|
Points[7] := aDoor.ca2;
|
|
Points[7].z := door_h2;
|
|
WallSides := CollectWall(aFaces, Points, AdjoiningList, []);
|
|
SetWallTypeToWallSide(WallSides, wstRight, fwtNiche, xWallElement);
|
|
|
|
// ïîñòðîèòü áëîê ñòåíû ñíèçó
|
|
Points[0] := aDoor.a1;
|
|
Points[0].z := wall_h1;
|
|
Points[1] := aDoor.a2;
|
|
Points[1].z := wall_h1;
|
|
Points[2] := aDoor.b1;
|
|
Points[2].z := wall_h1;
|
|
Points[3] := aDoor.b2;
|
|
Points[3].z := wall_h1;
|
|
Points[4] := aDoor.a1;
|
|
Points[4].z := door_h1;
|
|
Points[5] := aDoor.a2;
|
|
Points[5].z := door_h1;
|
|
Points[6] := aDoor.b1;
|
|
Points[6].z := door_h1;
|
|
Points[7] := aDoor.b2;
|
|
Points[7].z := door_h1;
|
|
WallSides := CollectWall(aFaces, Points, AdjoiningList, []);
|
|
SetWallTypeToWallSide(WallSides, wstUpper, fwtNiche, xWallElement);
|
|
|
|
// ïîñòðîèòü áëîê ñòåíû ñâåðõó
|
|
Points[0] := aDoor.a1;
|
|
Points[0].z := door_h2;
|
|
Points[1] := aDoor.a2;
|
|
Points[1].z := door_h2;
|
|
Points[2] := aDoor.b1;
|
|
Points[2].z := door_h2;
|
|
Points[3] := aDoor.b2;
|
|
Points[3].z := door_h2;
|
|
Points[4] := aDoor.a1;
|
|
|
|
{
|
|
Points[4].z := wall_h2;
|
|
Points[5] := aDoor.a2;
|
|
Points[5].z := wall_h2;
|
|
Points[6] := aDoor.b1;
|
|
Points[6].z := wall_h2;
|
|
Points[7] := aDoor.b2;
|
|
Points[7].z := wall_h2;
|
|
}
|
|
|
|
// MARK
|
|
Points[4].z := CalcPointHeight(FPlanObject.l1, FPlanObject.l2, aDoor.a1, corner_side1, corner_side2);
|
|
Points[5] := aDoor.a2;
|
|
Points[5].z := CalcPointHeight(FPlanObject.l1, FPlanObject.l2, aDoor.a2, corner_side1, corner_side2);
|
|
Points[6] := aDoor.b1;
|
|
Points[6].z := CalcPointHeight(FPlanObject.r1, FPlanObject.r2, aDoor.b1, corner_side1, corner_side2);
|
|
Points[7] := aDoor.b2;
|
|
Points[7].z := CalcPointHeight(FPlanObject.r1, FPlanObject.r2, aDoor.b2, corner_side1, corner_side2);
|
|
WallSides := CollectWall(aFaces, Points, AdjoiningList, []);
|
|
SetWallTypeToWallSide(WallSides, wstUnder, fwtNiche, xWallElement);
|
|
//xWallElement.ReplaceNicheSides;
|
|
end;
|
|
|
|
PrevDoor := aDoor;
|
|
PrevDoorSCSCompon := DoorSCSCompon;
|
|
xPrevWallElement := xWallElement;
|
|
end;
|
|
WallViewType := [];
|
|
WallType := fwtNone;
|
|
if PrevDoor <> nil then
|
|
WallType := GetWallTypeByDoorType(PrevDoor);
|
|
if WallType in [fwtDoorSlope, fwtWindowSlope, fwtBalconSlope] then
|
|
WallViewType := WallViewType + [wvtNoLeftSide];
|
|
|
|
Points[0] := xl1;
|
|
Points[0].z := wall_h1;
|
|
Points[1] := FPlanObject.l2;
|
|
Points[1].z := wall_h1;
|
|
Points[2] := xr1;
|
|
Points[2].z := wall_h1;
|
|
Points[3] := FPlanObject.r2;
|
|
Points[3].z := wall_h1;
|
|
Points[4] := xl1;
|
|
|
|
{
|
|
Points[4].z := wall_h2;
|
|
Points[5] := FPlanObject.l2;
|
|
Points[5].z := wall_h2;
|
|
Points[6] := xr1;
|
|
Points[6].z := wall_h2;
|
|
Points[7] := FPlanObject.r2;
|
|
Points[7].z := wall_h2;
|
|
}
|
|
|
|
// MARK
|
|
Points[4].z := CalcPointHeight(FPlanObject.l1, FPlanObject.l2, xl1, corner_side1, corner_side2);
|
|
Points[5] := FPlanObject.l2;
|
|
Points[5].z := corner_side2;
|
|
Points[6] := xr1;
|
|
Points[6].z := CalcPointHeight(FPlanObject.r1, FPlanObject.r2, xr1, corner_side1, corner_side2);
|
|
Points[7] := FPlanObject.r2;
|
|
Points[7].z := corner_side2;
|
|
WallSides := CollectWall(aFaces, Points, AdjoiningList, WallViewType);
|
|
// ïîñòàâèòü òèï ñòåíû ïî ñëåäóþùåìó îáüåêòó TNetDoor
|
|
if WallType in [fwtNiche, fwtArc] then
|
|
SetWallTypeToWallSide(WallSides, wstLeftSide, WallType, xWallElement);
|
|
end
|
|
else
|
|
// åñëè âíóòðè íè÷åãî íåò (àëãîðèòì ïîñòðîåíèÿ ¹2)
|
|
begin
|
|
Points[0] := FPlanObject.l1;
|
|
Points[0].z := wall_h1;
|
|
Points[1] := FPlanObject.l2;
|
|
Points[1].z := wall_h1;
|
|
Points[2] := FPlanObject.r1;
|
|
Points[2].z := wall_h1;
|
|
Points[3] := FPlanObject.r2;
|
|
Points[3].z := wall_h1;
|
|
Points[4] := FPlanObject.l1;
|
|
|
|
{
|
|
Points[4].z := wall_h2;
|
|
Points[5] := FPlanObject.l2;
|
|
Points[5].z := wall_h2;
|
|
Points[6] := FPlanObject.r1;
|
|
Points[6].z := wall_h2;
|
|
Points[7] := FPlanObject.r2;
|
|
Points[7].z := wall_h2;
|
|
}
|
|
|
|
// MARK
|
|
Points[4].z := corner_side1;
|
|
Points[5] := FPlanObject.l2;
|
|
Points[5].z := corner_side2;
|
|
Points[6] := FPlanObject.r1;
|
|
Points[6].z := corner_side1;
|
|
Points[7] := FPlanObject.r2;
|
|
Points[7].z := corner_side2;
|
|
WallSides := CollectWall(aFaces, Points, AdjoiningList, []);
|
|
end;
|
|
if WallSides <> nil then
|
|
FreeAndNil(WallSides);
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWall.ParseWall', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DWall.ReadFromStream(Stream: TStream);
|
|
var
|
|
isOk: Boolean;
|
|
xCode, xSize: Integer;
|
|
intVal: Integer;
|
|
byteVal: Byte;
|
|
wordVal: Word;
|
|
strVal: string;
|
|
dblval: Double;
|
|
xByte: pByte;
|
|
begin
|
|
try
|
|
isOk := False;
|
|
FName := ReadStringFromStream(Stream);
|
|
repeat
|
|
xCode := 0;
|
|
Stream.Read(xCode, 1);
|
|
if (xCode >= 20) and (xCode < 90) then
|
|
begin
|
|
Stream.Read(intVal, 4);
|
|
Case xcode of
|
|
20: FParentIndex := IntVal;
|
|
21: FSCSComponID := intVal;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 90) and (xCode < 120) then
|
|
begin
|
|
Stream.Read(byteVal, 1);
|
|
case xCode of
|
|
90: begin
|
|
if byteVal = 0 then
|
|
FIsArc := False
|
|
else
|
|
FIsArc := True;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 120) and (xCode < 150) then
|
|
begin
|
|
Stream.Read(wordVal, 2);
|
|
end
|
|
else
|
|
if (xCode >= 150) and (xCode < 180) then
|
|
begin
|
|
Stream.Read(xSize, 4);
|
|
end
|
|
else
|
|
if (xCode >= 180) and (xCode < 220) then
|
|
begin
|
|
strval := ReadStringFromStream(Stream);
|
|
case xCode of
|
|
180: isOk := true;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 220) and (xCode < 240) then
|
|
begin
|
|
Stream.Read(dblval, 8);
|
|
end;
|
|
until isOk;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWall.ReadFromStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DWall.SetRelations;
|
|
begin
|
|
try
|
|
if FParentIndex = - 1 then
|
|
begin
|
|
FParent := nil;
|
|
end
|
|
else
|
|
begin
|
|
FParent := T3DRoom(ModelObjectsList.Items[FParentIndex]);
|
|
T3DRoom(FParent).FWalls.Add(self);
|
|
end;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWall.SetRelations', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DWall.SetWallTypeToWallSide(aWallSides: TList; aWallSideType: TWallSideType;
|
|
aWallType: TFaceWallType; aWallElement: T3DWallElement);
|
|
var
|
|
i: integer;
|
|
WallSide: T3DSide;
|
|
begin
|
|
try
|
|
for i := 0 to aWallSides.Count - 1 do
|
|
begin
|
|
WallSide := T3DSide(aWallSides[i]);
|
|
if WallSide.FFace.FWallSideType = aWallSideType then
|
|
begin
|
|
WallSide.FFace.FFaceWallType := aWallType;
|
|
WallSide.FWallType := aWallType;
|
|
if (aWallType = fwtNiche) or (aWallType = fwtArc) then
|
|
begin
|
|
aWallElement.FSides.Add(WallSide);
|
|
FSides.Remove(WallSide);
|
|
end;
|
|
Break;
|
|
end;
|
|
end;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWall.SetWallTypeToWallSide', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DWall.WriteToStream(Stream: TStream);
|
|
var
|
|
xInt: Integer;
|
|
xByte: Byte;
|
|
begin
|
|
try
|
|
WriteString(Stream, FClassName);
|
|
WriteString(Stream, FName);
|
|
xInt := ModelObjectsList.IndexOf(FParent);
|
|
WriteField(20, Stream, xInt, sizeof(xInt));
|
|
xInt := FSCSComponID;
|
|
WriteField(21, Stream, xInt, sizeof(xInt));
|
|
if FIsArc then
|
|
xByte := 1
|
|
else
|
|
xByte := 0;
|
|
WriteField(90, Stream, xByte, sizeof(xByte));
|
|
WriteStrField(180, Stream, 'BaseEnd');
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWall.WriteToStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
{ T3DWallElement }
|
|
|
|
procedure T3DWallElement.CollectBalcon(aFaces: TList; ap1, ap2: T3DPointArray);
|
|
var
|
|
a3DPointArr: T3DPointArray;
|
|
aFace: TFaceRecord;
|
|
xBalconElement: T3DBalconElement;
|
|
begin
|
|
try
|
|
xBalconElement := T3DBalconElement.Create(aFaces, dotDoor, self);
|
|
xBalconElement.FSCSCompon := GetChildComponByIsLine(FSCSCompon, ctArhDoor);
|
|
xBalconElement.FSCSComponID := xBalconElement.FSCSCompon.ID;
|
|
xBalconElement.FName := xBalconElement.FSCSCompon.Name;
|
|
xBalconElement.CollectBalconDoor(aFaces, ap1);
|
|
FBalconElements.Add(xBalconElement);
|
|
|
|
xBalconElement := T3DBalconElement.Create(aFaces, dotWindow, self);
|
|
xBalconElement.FSCSCompon := GetChildComponByIsLine(FSCSCompon, ctArhWindow);
|
|
xBalconElement.FSCSComponID := xBalconElement.FSCSCompon.ID;
|
|
xBalconElement.FName := xBalconElement.FSCSCompon.Name;
|
|
xBalconElement.CollectBalconWindow(aFaces, ap2);
|
|
FBalconElements.Add(xBalconElement);
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWallElement.CollectBalcon', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DWallElement.CollectDoor(aFaces: TList; ap: T3DPointArray);
|
|
var
|
|
a3DPointArr: T3DPointArray;
|
|
aFace: TFaceRecord;
|
|
xSide: T3DSide;
|
|
begin
|
|
try
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap[0];
|
|
a3DPointArr[1] := ap[1];
|
|
a3DPointArr[2] := ap[3];
|
|
a3DPointArr[3] := ap[2];
|
|
xSide := T3DSide.Create(ftNetDoor, fwtNone, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap[4];
|
|
a3DPointArr[1] := ap[5];
|
|
a3DPointArr[2] := ap[7];
|
|
a3DPointArr[3] := ap[6];
|
|
xSide := T3DSide.Create(ftNetDoor, fwtNone, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap[0];
|
|
a3DPointArr[1] := ap[1];
|
|
a3DPointArr[2] := ap[5];
|
|
a3DPointArr[3] := ap[4];
|
|
xSide := T3DSide.Create(ftNetDoor, fwtNone, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap[2];
|
|
a3DPointArr[1] := ap[3];
|
|
a3DPointArr[2] := ap[7];
|
|
a3DPointArr[3] := ap[6];
|
|
xSide := T3DSide.Create(ftNetDoor, fwtNone, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap[0];
|
|
a3DPointArr[1] := ap[4];
|
|
a3DPointArr[2] := ap[6];
|
|
a3DPointArr[3] := ap[2];
|
|
xSide := T3DSide.Create(ftNetDoor, fwtNone, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap[1];
|
|
a3DPointArr[1] := ap[5];
|
|
a3DPointArr[2] := ap[7];
|
|
a3DPointArr[3] := ap[3];
|
|
xSide := T3DSide.Create(ftNetDoor, fwtNone, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWallElement.CollectDoor', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DWallElement.CollectWindow(aFaces: TList; ap: T3DPointArray);
|
|
var
|
|
a3DPointArr: T3DPointArray;
|
|
aFace: TFaceRecord;
|
|
xSide: T3DSide;
|
|
begin
|
|
try
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap[0];
|
|
a3DPointArr[1] := ap[1];
|
|
a3DPointArr[2] := ap[3];
|
|
a3DPointArr[3] := ap[2];
|
|
xSide := T3DSide.Create(ftNetWindow, fwtNone, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap[4];
|
|
a3DPointArr[1] := ap[5];
|
|
a3DPointArr[2] := ap[7];
|
|
a3DPointArr[3] := ap[6];
|
|
xSide := T3DSide.Create(ftNetWindow, fwtNone, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap[0];
|
|
a3DPointArr[1] := ap[1];
|
|
a3DPointArr[2] := ap[5];
|
|
a3DPointArr[3] := ap[4];
|
|
xSide := T3DSide.Create(ftNetWindow, fwtNone, wstNone, self );
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr, True);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap[2];
|
|
a3DPointArr[1] := ap[3];
|
|
a3DPointArr[2] := ap[7];
|
|
a3DPointArr[3] := ap[6];
|
|
xSide := T3DSide.Create(ftNetWindow, fwtNone, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr, True);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap[0];
|
|
a3DPointArr[1] := ap[4];
|
|
a3DPointArr[2] := ap[6];
|
|
a3DPointArr[3] := ap[2];
|
|
xSide := T3DSide.Create(ftNetWindow, fwtNone, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap[1];
|
|
a3DPointArr[1] := ap[5];
|
|
a3DPointArr[2] := ap[7];
|
|
a3DPointArr[3] := ap[3];
|
|
xSide := T3DSide.Create(ftNetWindow, fwtNone, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWallElement.CollectWindow', E.Message);
|
|
end;
|
|
end;
|
|
|
|
constructor T3DWallElement.Create(aFaces: TList; aNetDoor: TNetDoor; aElementType: TDoorObjType; aParent: T3DWall);
|
|
begin
|
|
try
|
|
inherited Create;
|
|
FClassName := 'T3DWallElement';
|
|
FPlanObject := aNetDoor;
|
|
if aNetDoor <> nil then
|
|
begin
|
|
FSCSCompon := GetArchObjByCADObj(aNetDoor);
|
|
FSCSComponID := FSCSCompon.ID;
|
|
FName := FSCSCompon.Name + ' ' + FSCSCompon.NameMark;
|
|
end;
|
|
FParent := aParent;
|
|
FElementType := aElementType;
|
|
FSlopes := TList.Create;
|
|
FSides := TList.Create;
|
|
FBalconElements := TList.Create;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWallElement.Create', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DWallElement.ReadFromStream(Stream: TStream);
|
|
var
|
|
isOk: Boolean;
|
|
xCode, xSize: Integer;
|
|
intVal: Integer;
|
|
byteVal: Byte;
|
|
wordVal: Word;
|
|
strVal: string;
|
|
dblval: Double;
|
|
xByte: pByte;
|
|
begin
|
|
try
|
|
isOk := False;
|
|
FName := ReadStringFromStream(Stream);
|
|
repeat
|
|
xCode := 0;
|
|
Stream.Read(xCode, 1);
|
|
if (xCode >= 20) and (xCode < 90) then
|
|
begin
|
|
Stream.Read(intVal, 4);
|
|
Case xcode of
|
|
20: FParentIndex := IntVal;
|
|
21: FSCSComponID := intVal;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 90) and (xCode < 120) then
|
|
begin
|
|
Stream.Read(byteVal, 1);
|
|
end
|
|
else
|
|
if (xCode >= 120) and (xCode < 150) then
|
|
begin
|
|
Stream.Read(wordVal, 2);
|
|
end
|
|
else
|
|
if (xCode >= 150) and (xCode < 180) then
|
|
begin
|
|
Stream.Read(xSize, 4);
|
|
end
|
|
else
|
|
if (xCode >= 180) and (xCode < 220) then
|
|
begin
|
|
strval := ReadStringFromStream(Stream);
|
|
case xCode of
|
|
180: isOk := true;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 220) and (xCode < 240) then
|
|
begin
|
|
Stream.Read(dblval, 8);
|
|
end;
|
|
until isOk;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWallElement.ReadFromStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DWallElement.ReplaceArcSides;
|
|
var
|
|
i, j: integer;
|
|
xSide: T3DSide;
|
|
begin
|
|
try
|
|
for i := 0 to FParent.FSides.Count - 1 do
|
|
begin
|
|
xSide := T3DSide(FParent.FSides[i]);
|
|
if xSide.FWallType = fwtArc then
|
|
begin
|
|
FSides.Add(xSide);
|
|
end;
|
|
end;
|
|
for i := 0 to FSides.Count - 1 do
|
|
begin
|
|
xSide := T3DSide(FSides[i]);
|
|
FParent.FSides.Remove(xSide);
|
|
end;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWallElement.ReplaceArcSides', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DWallElement.ReplaceNicheSides;
|
|
var
|
|
i, j: integer;
|
|
xSide: T3DSide;
|
|
begin
|
|
try
|
|
for i := 0 to FParent.FSides.Count - 1 do
|
|
begin
|
|
xSide := T3DSide(FParent.FSides[i]);
|
|
if xSide.FWallType = fwtNiche then
|
|
begin
|
|
FSides.Add(xSide);
|
|
end;
|
|
end;
|
|
for i := 0 to FSides.Count - 1 do
|
|
begin
|
|
xSide := T3DSide(FSides[i]);
|
|
FParent.FSides.Remove(xSide);
|
|
end;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWallElement.ReplaceNicheSides', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DWallElement.SetRelations;
|
|
begin
|
|
try
|
|
if FParentIndex = - 1 then
|
|
begin
|
|
FParent := nil;
|
|
end
|
|
else
|
|
begin
|
|
FParent := T3DWall(ModelObjectsList.Items[FParentIndex]);
|
|
T3DWall(FParent).FWallElements.Add(self);
|
|
end;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWallElement.SetRelations', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DWallElement.WriteToStream(Stream: TStream);
|
|
var
|
|
xInt: Integer;
|
|
begin
|
|
try
|
|
WriteString(Stream, FClassName);
|
|
WriteString(Stream, FName);
|
|
xInt := ModelObjectsList.IndexOf(FParent);
|
|
WriteField(20, Stream, xInt, sizeof(xInt));
|
|
xInt := FSCSComponID;
|
|
WriteField(21, Stream, xInt, sizeof(xInt));
|
|
WriteStrField(180, Stream, 'BaseEnd');
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DWallElement.WriteToStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
{ T3DSlope }
|
|
|
|
constructor T3DSlope.Create(aFaces: TList; aNetDoor: TNetDoor; aParent: T3DWallElement);
|
|
begin
|
|
try
|
|
inherited Create;
|
|
FClassName := 'T3DSlope';
|
|
if aNetDoor <> nil then
|
|
begin
|
|
FSCSCompon := GetArchObjByCADObj(aNetDoor);
|
|
FSCSComponID := FSCSCompon.ID;
|
|
end;
|
|
FParent := aParent;
|
|
FSides := TList.Create;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DSlope.Create', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DSlope.ReadFromStream(Stream: TStream);
|
|
var
|
|
isOk: Boolean;
|
|
xCode, xSize: Integer;
|
|
intVal: Integer;
|
|
byteVal: Byte;
|
|
wordVal: Word;
|
|
strVal: string;
|
|
dblval: Double;
|
|
xByte: pByte;
|
|
begin
|
|
try
|
|
isOk := False;
|
|
FName := ReadStringFromStream(Stream);
|
|
repeat
|
|
xCode := 0;
|
|
Stream.Read(xCode, 1);
|
|
if (xCode >= 20) and (xCode < 90) then
|
|
begin
|
|
Stream.Read(intVal, 4);
|
|
Case xcode of
|
|
20: FParentIndex := IntVal;
|
|
21: FSCSComponID := intVal;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 90) and (xCode < 120) then
|
|
begin
|
|
Stream.Read(byteVal, 1);
|
|
end
|
|
else
|
|
if (xCode >= 120) and (xCode < 150) then
|
|
begin
|
|
Stream.Read(wordVal, 2);
|
|
end
|
|
else
|
|
if (xCode >= 150) and (xCode < 180) then
|
|
begin
|
|
Stream.Read(xSize, 4);
|
|
end
|
|
else
|
|
if (xCode >= 180) and (xCode < 220) then
|
|
begin
|
|
strval := ReadStringFromStream(Stream);
|
|
case xCode of
|
|
180: isOk := true;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 220) and (xCode < 240) then
|
|
begin
|
|
Stream.Read(dblval, 8);
|
|
end;
|
|
until isOk;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DSlope.ReadFromStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DSlope.SetRelations;
|
|
begin
|
|
try
|
|
if FParentIndex = - 1 then
|
|
begin
|
|
FParent := nil;
|
|
end
|
|
else
|
|
begin
|
|
FParent := T3DWallElement(ModelObjectsList.Items[FParentIndex]);
|
|
T3DWallElement(FParent).FSlopes.Add(self);
|
|
end;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DSlope.SetRelations', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DSlope.WriteToStream(Stream: TStream);
|
|
var
|
|
xInt: Integer;
|
|
begin
|
|
try
|
|
WriteString(Stream, FClassName);
|
|
WriteString(Stream, FName);
|
|
xInt := ModelObjectsList.IndexOf(FParent);
|
|
WriteField(20, Stream, xInt, sizeof(xInt));
|
|
xInt := FSCSComponID;
|
|
WriteField(21, Stream, xInt, sizeof(xInt));
|
|
WriteStrField(180, Stream, 'BaseEnd');
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DSlope.WriteToStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
{ T3DBalconElement }
|
|
|
|
procedure T3DBalconElement.CollectBalconDoor(aFaces: TList; ap1: T3DPointArray);
|
|
var
|
|
a3DPointArr: T3DPointArray;
|
|
aFace: TFaceRecord;
|
|
xSide: T3DSide;
|
|
begin
|
|
try
|
|
// ñîáðàòü áàëêîííóþ äâåðü
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap1[0];
|
|
a3DPointArr[1] := ap1[1];
|
|
a3DPointArr[2] := ap1[3];
|
|
a3DPointArr[3] := ap1[2];
|
|
xSide := T3DSide.Create(ftNetBalconDoor, fwtBalconSlope, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap1[4];
|
|
a3DPointArr[1] := ap1[5];
|
|
a3DPointArr[2] := ap1[7];
|
|
a3DPointArr[3] := ap1[6];
|
|
xSide := T3DSide.Create(ftNetBalconDoor, fwtBalconSlope, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap1[0];
|
|
a3DPointArr[1] := ap1[1];
|
|
a3DPointArr[2] := ap1[5];
|
|
a3DPointArr[3] := ap1[4];
|
|
xSide := T3DSide.Create(ftNetBalconDoor, fwtBalconSlope, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr, True);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap1[2];
|
|
a3DPointArr[1] := ap1[3];
|
|
a3DPointArr[2] := ap1[7];
|
|
a3DPointArr[3] := ap1[6];
|
|
xSide := T3DSide.Create(ftNetBalconDoor, fwtBalconSlope, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr, True { Trans });
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap1[0];
|
|
a3DPointArr[1] := ap1[4];
|
|
a3DPointArr[2] := ap1[6];
|
|
a3DPointArr[3] := ap1[2];
|
|
xSide := T3DSide.Create(ftNetBalconDoor, fwtBalconSlope, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap1[1];
|
|
a3DPointArr[1] := ap1[5];
|
|
a3DPointArr[2] := ap1[7];
|
|
a3DPointArr[3] := ap1[3];
|
|
xSide := T3DSide.Create(ftNetBalconDoor, fwtBalconSlope, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DBalconElement.CollectBalconDoor', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DBalconElement.CollectBalconWindow(aFaces: TList; ap2: T3DPointArray);
|
|
var
|
|
a3DPointArr: T3DPointArray;
|
|
aFace: TFaceRecord;
|
|
xSide: T3DSide;
|
|
begin
|
|
try
|
|
// ñîáðàòü áàëêîííîå îêíî
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap2[0];
|
|
a3DPointArr[1] := ap2[1];
|
|
a3DPointArr[2] := ap2[3];
|
|
a3DPointArr[3] := ap2[2];
|
|
xSide := T3DSide.Create(ftNetBalconWindow, fwtBalconSlope, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap2[4];
|
|
a3DPointArr[1] := ap2[5];
|
|
a3DPointArr[2] := ap2[7];
|
|
a3DPointArr[3] := ap2[6];
|
|
xSide := T3DSide.Create(ftNetBalconWindow, fwtBalconSlope, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap2[0];
|
|
a3DPointArr[1] := ap2[1];
|
|
a3DPointArr[2] := ap2[5];
|
|
a3DPointArr[3] := ap2[4];
|
|
xSide := T3DSide.Create(ftNetBalconWindow, fwtBalconSlope, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr, True);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap2[2];
|
|
a3DPointArr[1] := ap2[3];
|
|
a3DPointArr[2] := ap2[7];
|
|
a3DPointArr[3] := ap2[6];
|
|
xSide := T3DSide.Create(ftNetBalconWindow, fwtBalconSlope, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr, True);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap2[0];
|
|
a3DPointArr[1] := ap2[4];
|
|
a3DPointArr[2] := ap2[6];
|
|
a3DPointArr[3] := ap2[2];
|
|
xSide := T3DSide.Create(ftNetBalconWindow, fwtBalconSlope, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
SetLength(a3DPointArr, 4);
|
|
a3DPointArr[0] := ap2[1];
|
|
a3DPointArr[1] := ap2[5];
|
|
a3DPointArr[2] := ap2[7];
|
|
a3DPointArr[3] := ap2[3];
|
|
xSide := T3DSide.Create(ftNetBalconWindow, fwtBalconSlope, wstNone, self);
|
|
xSide.CollectWallElementSide(aFaces, a3DPointArr);
|
|
FSides.Add(xSide);
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DBalconElement.CollectBalconWindow', E.Message);
|
|
end;
|
|
end;
|
|
|
|
constructor T3DBalconElement.Create(aFaces: TList; aElementType: TDoorObjType; aParent: T3DWallElement);
|
|
begin
|
|
try
|
|
inherited Create;
|
|
FClassName := 'T3DBalconElement';
|
|
FParent := aParent;
|
|
FElementType := aElementType;
|
|
FSides := TList.Create;
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DBalconElement.Create', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DBalconElement.ReadFromStream(Stream: TStream);
|
|
var
|
|
isOk: Boolean;
|
|
xCode, xSize: Integer;
|
|
intVal: Integer;
|
|
byteVal: Byte;
|
|
wordVal: Word;
|
|
strVal: string;
|
|
dblval: Double;
|
|
xByte: pByte;
|
|
begin
|
|
try
|
|
isOk := False;
|
|
FName := ReadStringFromStream(Stream);
|
|
repeat
|
|
xCode := 0;
|
|
Stream.Read(xCode, 1);
|
|
if (xCode >= 20) and (xCode < 90) then
|
|
begin
|
|
Stream.Read(intVal, 4);
|
|
Case xcode of
|
|
20: FParentIndex := IntVal;
|
|
21: FSCSComponID := intVal;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 90) and (xCode < 120) then
|
|
begin
|
|
Stream.Read(byteVal, 1);
|
|
end
|
|
else
|
|
if (xCode >= 120) and (xCode < 150) then
|
|
begin
|
|
Stream.Read(wordVal, 2);
|
|
end
|
|
else
|
|
if (xCode >= 150) and (xCode < 180) then
|
|
begin
|
|
Stream.Read(xSize, 4);
|
|
end
|
|
else
|
|
if (xCode >= 180) and (xCode < 220) then
|
|
begin
|
|
strval := ReadStringFromStream(Stream);
|
|
case xCode of
|
|
180: isOk := true;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 220) and (xCode < 240) then
|
|
begin
|
|
Stream.Read(dblval, 8);
|
|
end;
|
|
until isOk;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DBalconElement.ReadFromStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DBalconElement.SetRelations;
|
|
begin
|
|
try
|
|
if FParentIndex = - 1 then
|
|
begin
|
|
FParent := nil;
|
|
end
|
|
else
|
|
begin
|
|
FParent := T3DWallElement(ModelObjectsList.Items[FParentIndex]);
|
|
T3DWallElement(FParent).FBalconElements.Add(self);
|
|
end;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DBalconElement.SetRelations', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DBalconElement.WriteToStream(Stream: TStream);
|
|
var
|
|
xInt: Integer;
|
|
begin
|
|
try
|
|
WriteString(Stream, FClassName);
|
|
WriteString(Stream, FName);
|
|
xInt := ModelObjectsList.IndexOf(FParent);
|
|
WriteField(20, Stream, xInt, sizeof(xInt));
|
|
xInt := FSCSComponID;
|
|
WriteField(21, Stream, xInt, sizeof(xInt));
|
|
WriteStrField(180, Stream, 'BaseEnd');
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DBalconElement.WriteToStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
{ T3DSObject }
|
|
|
|
constructor T3DSObject.Create(aParent: T3DRoom);
|
|
begin
|
|
try
|
|
inherited Create;
|
|
FClassName := 'T3DSObject';
|
|
FName := '';
|
|
FDescription := TStringList.Create;
|
|
FParent := aParent;
|
|
FGLObject := nil;
|
|
FFace := nil;
|
|
FScale.x := 1;
|
|
FScale.y := 1;
|
|
FScale.z := 1;
|
|
FPosition.x := 0;
|
|
FPosition.y := 0;
|
|
FPosition.z := 0;
|
|
FRotate.x := 0;
|
|
FRotate.y := 0;
|
|
FRotate.z := 0;
|
|
FPath := '';
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DSObject.Create', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DSObject.ReadFromStream(Stream: TStream);
|
|
var
|
|
isOk: Boolean;
|
|
xCode, xSize: Integer;
|
|
intVal: Integer;
|
|
byteVal: Byte;
|
|
wordVal: Word;
|
|
strVal: string;
|
|
dblval: Double;
|
|
xByte: pByte;
|
|
xd, yd, zd: Double;
|
|
begin
|
|
try
|
|
isOk := False;
|
|
FName := ReadStringFromStream(Stream);
|
|
repeat
|
|
xCode := 0;
|
|
Stream.Read(xCode, 1);
|
|
if (xCode >= 20) and (xCode < 90) then
|
|
begin
|
|
Stream.Read(intVal, 4);
|
|
Case xcode of
|
|
20: FParentIndex := IntVal;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 90) and (xCode < 120) then
|
|
begin
|
|
Stream.Read(byteVal, 1);
|
|
end
|
|
else
|
|
if (xCode >= 120) and (xCode < 150) then
|
|
begin
|
|
Stream.Read(wordVal, 2);
|
|
end
|
|
else
|
|
if (xCode >= 150) and (xCode < 180) then
|
|
begin
|
|
Stream.Read(xSize, 4);
|
|
Case xcode of
|
|
150: begin
|
|
Stream.read(xd, 8);
|
|
Stream.read(yd, 8);
|
|
Stream.read(zd, 8);
|
|
FPosition.x := xd;
|
|
FPosition.y := yd;
|
|
FPosition.z := zd;
|
|
end;
|
|
151: begin
|
|
Stream.read(xd, 8);
|
|
Stream.read(yd, 8);
|
|
Stream.read(zd, 8);
|
|
FScale.x := xd;
|
|
FScale.y := yd;
|
|
FScale.z := zd;
|
|
end;
|
|
152: begin
|
|
Stream.read(xd, 8);
|
|
Stream.read(yd, 8);
|
|
Stream.read(zd, 8);
|
|
FRotate.x := xd;
|
|
FRotate.y := yd;
|
|
FRotate.z := zd;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 180) and (xCode < 220) then
|
|
begin
|
|
strval := ReadStringFromStream(Stream);
|
|
case xCode of
|
|
180: isOk := true;
|
|
181: FDescription.Text := strVal;
|
|
182: FPath := strVal;
|
|
end;
|
|
end
|
|
else
|
|
if (xCode >= 220) and (xCode < 240) then
|
|
begin
|
|
Stream.Read(dblval, 8);
|
|
end;
|
|
until isOk;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DSObject.ReadFromStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DSObject.SetRelations;
|
|
begin
|
|
try
|
|
if FParentIndex = - 1 then
|
|
begin
|
|
FParent := nil;
|
|
end
|
|
else
|
|
begin
|
|
FParent := T3DRoom(ModelObjectsList.Items[FParentIndex]);
|
|
T3DRoom(FParent).F3DSObjects.Add(self);
|
|
end;
|
|
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DSObject.SetRelations', E.Message);
|
|
end;
|
|
end;
|
|
|
|
procedure T3DSObject.WriteToStream(Stream: TStream);
|
|
var
|
|
i, xCount, xInt: Integer;
|
|
xByte: Byte;
|
|
xStr: string;
|
|
xDouble: Double;
|
|
aPoint: pInt;
|
|
|
|
begin
|
|
try
|
|
WriteString(Stream, FClassName);
|
|
WriteString(Stream, FName);
|
|
xInt := ModelObjectsList.IndexOf(FParent);
|
|
WriteField(20, Stream, xInt, sizeof(xInt));
|
|
|
|
GetMem(aPoint, 24);
|
|
pDouble(pChar(aPoint) + 0)^ := FPosition.x;
|
|
pDouble(pChar(aPoint) + 8)^ := FPosition.y;
|
|
pDouble(pChar(aPoint) + 16)^ := FPosition.z;
|
|
WriteBinField(150, Stream, pByte(aPoint), 24);
|
|
FreeMem(aPoint, 24);
|
|
|
|
GetMem(aPoint, 24);
|
|
pDouble(pChar(aPoint) + 0)^ := FScale.x;
|
|
pDouble(pChar(aPoint) + 8)^ := FScale.y;
|
|
pDouble(pChar(aPoint) + 16)^ := FScale.z;
|
|
WriteBinField(151, Stream, pByte(aPoint), 24);
|
|
FreeMem(aPoint, 24);
|
|
|
|
GetMem(aPoint, 24);
|
|
pDouble(pChar(aPoint) + 0)^ := FRotate.x;
|
|
pDouble(pChar(aPoint) + 8)^ := FRotate.y;
|
|
pDouble(pChar(aPoint) + 16)^ := FRotate.z;
|
|
WriteBinField(152, Stream, pByte(aPoint), 24);
|
|
FreeMem(aPoint, 24);
|
|
|
|
WriteStrField(181, Stream, FDescription.Text);
|
|
WriteStrField(182, Stream, FPath);
|
|
WriteStrField(180, Stream, 'BaseEnd');
|
|
except
|
|
on E: Exception do AddExceptionToLogEx('T3DSObject.WriteToStream', E.Message);
|
|
end;
|
|
end;
|
|
|
|
end.
|