![]()  | 
	
 
  | 
		
			
  | 	
	
	
		
		|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны | 
![]()  | 
	
	
| 
		 | 
	Опции темы | Поиск в этой теме | Опции просмотра | 
| 
		 
			 
			#1  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Доброго всем. 
		
	
		
		
		
		
		
	
		
		
	
	
	Есть стандартный файл литографии STL - дока в сети есть но всёже приведу Его структура: 80 первых байт текст - комменты 4 байта число элементов (треугольников) (тип Dword) 4 по 4 Real32 - нормаль XYZ и координаты ХYZ вершин треугольника 2 байта вспомогательная инфа. и того 80 + 4 + 50 + 50 +50 +.....+50(раз элементов). составляю типы: Код: 
	type triangle=record nv:single tx:single ty:single tz:single tc:word end type mstl=record comm:string // 80 numt:dword // 4 ztrian:triangle // 50 end К тому же не ясно, как перебирать в таком типе все треугольники (50 байт 4х4 +2) при чтении указывать как массив(максючисло треуг.допустим 6000000): ztrian:array [0..6000000] of triangle . А как писать обратно в такой файл? и если писать массив то запишется весь??? (6000000???) а мне надо скажем 10000 всего? Что не делаю то I/O error или вместо данных (достоверно прочтёных в фирменной программе) получаю не координаты и сумашедшие числа... ХЕЛП...  | 
| 
		 
			 
			#2  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 1. Читать через TFileStream 
		
	
		
		
		
		
		
	
		
		
	
	
	2. Перед чтением надо память выделять Как-то так: Код: 
	type
  TSTLItem = record
    nv:single
    tx:single
    ty:single
    tz:single
    tc:word
  end;
  TSTLStruct = record
    Comm : AnsiString;
    Count : DWORD;
    Items : Array Of TSTLItem;
  end;
procedure ReadSTLFile(FileName : String; var Data : TSTLStruct);
var
  I : Integer;
  F : TFileStream;
begin
  F := TFileStream.Create(FileName, fmOpenRead);
  Try
    SetLength(Data.Comm,80);
    F.ReadBuffer(Data.Comm[1],80);
    F.ReadBuffer(Data.Count,sizeOf(DWORD));
    SetLength(Data.Items,Data.Count);
    For I := 0 To Data.Count-1 Do
      Begin
        F.ReadBuffer(Data.Items[i].nv,SizeOf(Single));
        // Здесь читаем остальные поля текущего треугольника
      End;
  Finally
    F.Free;
  end;
end; | 
| 
		 
			 
			#3  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 ТС похоже немного заблуждается, если судить по описанию бинарной версии данного формата, то структура записей должна быть слегка другой, с чтением из буфера не дружу, но вот такой вариант загрузил координаты треугольников тестового чайника из teapot.stl 
		
	
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	Код: 
	type
  TSTLItem = record
    ni: single;
    nj: single;
    nk: single;
    x1: single;
    y1: single;
    z1: single;
    x2: single;
    y2: single;
    z2: single;
    x3: single;
    y3: single;
    z3: single;
    tc: word;
  end;
   TSTLStruct = record
    Comm : String[80];
    Count : DWORD;
    Items : Array Of TSTLItem;
  end;
var
 Data : TSTLStruct;
 StlFile: TFileStream;
 b: dword;
begin
  StlFile:= TFileStream.Create(FileName, fmOpenRead);
  StlFile.Seek(0, soFromBeginning);
  StlFile.Read(Data.comm,80);
  StlFile.Read(Data.Count,4);
  SetLength(Data.Items,Data.Count);
  for b:= 0 to Data.Count-1 do
   begin
    StlFile.Read(Data.Items[b].ni,4);
    StlFile.Read(Data.Items[b].nj,4);
    StlFile.Read(Data.Items[b].nk,4);
    StlFile.Read(Data.Items[b].x1,4);
    StlFile.Read(Data.Items[b].y1,4);
    StlFile.Read(Data.Items[b].z1,4);
    StlFile.Read(Data.Items[b].x2,4);
    StlFile.Read(Data.Items[b].y2,4);
    StlFile.Read(Data.Items[b].z2,4);
    StlFile.Read(Data.Items[b].x3,4);
    StlFile.Read(Data.Items[b].y3,4);
    StlFile.Read(Data.Items[b].z3,4);
    StlFile.Read(Data.Items[b].tc,2);
   end;
 StlFile.Free;
  end; | 
| 
		 
			 
			#4  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Прочитать могу только  < примерно 40000 треугольников и а если ставлю больше то Stack Overflow, если не ставлю размер - то вообще не компилит. 
		
	
		
		
		
		
		
	
		
		
	
	
	Вот моя полная процедура: Код: 
	procedure TForm1.Button1Click(Sender: TObject);  // загрузить файл точек/бинарник/треугольники
type
  striangle=packed record           // 50_и байтная запись 1 треугольника
  trnormx:single;       // 4
  trnormy:single;       // 4
  trnormz:single;       // 4
  tr3dx1: Single;       // 4
  tr3dy1: Single;       // 4
  tr3dz1: Single;       // 4
  tr3dx2: Single;       // 4
  tr3dy2: Single;       // 4
  tr3dz2: Single;       // 4
  tr3dx3: Single;       // 4
  tr3dy3: Single;       // 4
  tr3dz3: Single;       // 4
  trattr: word;         // 2
end;
type
  StlRec= packed record
    SName: array[1..80] of Char;//string[80];      // array of char  сработал правильно
    Snum: dword;
    msstri: array [0..60000]of striangle;         // множество записей треугольничных записей - 60000 уже не берёт 
end;
var
i,ii,jj,sl:integer;
sss,stru:string;
Buf: array[1..127] of Char;
mash:single;
NumRead: integer;
Infl: file of Single;
//stlf: file;
stlperm: StlRec;
stlf: file of StlRec;
begin
 mash:=strtofloat(Edit1.text);
 if OpenDialog1.Execute then
   begin
      if OpenDialog1.FilterIndex=3 then   //  STL bin file
        begin
          AssignFile(stlf,OpenDialog1.FileName);
          Reset(stlf);
          DlnStr:=80;
        //  BlockRead(stlf,,DlnStr,NumRead);                //читаем файл в массив
          read(stlf,stlperm);
       //   SetLength(stlperm.msstri, stlperm.Snum);    // попытка дать размер массиву треугольников
          DlnStr:=1;
         // ntri:=FilePos(stlf);// - возвращает текущую позицию чтения/записи в файл
      //    BlockRead(stlf,ntri,DlnStr,NumRead);
          DlnStr:=NumRead;                          //получили реальную длину файла
          CloseFile(stlf);
          ii:=21;
          i:=0;
         // ntri:=Fbind[20];    // запоминаем число треугольников для процедуры вывода графики
    //      memo1.Clear;
   //       SendMessage(memo1.Handle, WM_SETREDRAW, 0, 0) ;   // запрещаем перерисовку для ускорения вывода
          jlc:=stlperm.Snum;
        //  while i<(stlperm.Snum-1) do
          while i<(19999) do
            begin
//              ii:=ii+1;
//              stlperm.msstri[]                                 // перепрыгиваем направление нормали треугольника
              triangle3dx1[i]:= stlperm.msstri[i].tr3dx1;         // заполняем массив точками
              triangle3dy1[i]:= stlperm.msstri[i].tr3dy1;         // заполняем массив точками
              triangle3dz1[i]:= stlperm.msstri[i].tr3dz1;         // заполняем массив точками
              triangle3dx2[i]:= stlperm.msstri[i].tr3dx2;         // заполняем массив точками
              triangle3dy2[i]:= stlperm.msstri[i].tr3dy2;         // заполняем массив точками
              triangle3dz2[i]:= stlperm.msstri[i].tr3dz2;         // заполняем массив точками
              triangle3dx3[i]:= stlperm.msstri[i].tr3dx3;         // заполняем массив точками
              triangle3dy3[i]:= stlperm.msstri[i].tr3dy3;         // заполняем массив точками
              triangle3dz3[i]:= stlperm.msstri[i].tr3dz3;         // заполняем массив точками
              i:=i+1;
              ii:=i;
      //        memo1.Lines.Add(floattostrf(points3dx[i],fffixed,6,3)+' '+floattostrf(points3dy[i],fffixed,6,3)+' '+floattostrf(points3dz[i],fffixed,6,3));
       //       i:=i+1;
            end;  
      //    SendMessage(memo1.Handle, WM_SETREDRAW, 1, 0);     // разрешаем перерисовку
      //    RedrawWindow(memo1.Handle, nil, 0,RDW_ERASE or RDW_FRAME or RDW_INVALIDATE or RDW_ALLCHILDREN);
        end; // open STL
   end;// open file
 l_point:=true;
label1.Tag:=ii;
end;В принципе работает он но на малое число - 20000 точно берёт. Видел примеры что делают через Read/Seek по записям - но там нет заголовочной инфы и какие-то примеры не полноценные... Спасибо, попробую.  | 
| 
		 
			 
			#5  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Alegun Ваш код работает, спасибо, только число переменных больше и Data надо объявить (о, Вы уже дописали код ))), и в принципе я читал потом не в переменную файла а в массив типа single - всё нормально прочиталось и массив заполнился. 
		
	
		
		
		
		
		
	
		
		
	
	
	С этого массива сразу читал точки и в OpenGl строил треугольники - всё чётко. Всем спасибо )) ![]()  | 
| 
		 
			 
			#6  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Способом копипасты довёл число треугольников в текстовом варианте  больше чем 160000 штук, затем первёл в бинарный формат - прекрасно под D7 полученный файл и открывается и грузится в структуру, наверное с типами у вас неразбериха, отсюда и преполнение 
		
	
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	З.Ы. Есть менее затратный вариант - подключить к проекту assimp32.dll, порт объявы под делфи в сетке вроде на неё есть, а это умеет работать со многими форматами, в том числе и с двумя вариантами *.stl  | 
| Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
 
-=#PupaJr#=- (22.08.2016)
  | ||